home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / ImageMagick / magick / X.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  192.7 KB  |  6,346 lines

  1. /*
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. %                                                                             %
  4. %                                                                             %
  5. %                                                                             %
  6. %                                                                             %
  7. %                                   X   X                                     %
  8. %                                    X X                                      %
  9. %                                     X                                       %
  10. %                                    X X                                      %
  11. %                                   X   X                                     %
  12. %                                                                             %
  13. %                    X11 Utility Routines for ImageMagick.                    %
  14. %                                                                             %
  15. %                                                                             %
  16. %                               Software Design                               %
  17. %                                 John Cristy                                 %
  18. %                                  July 1992                                  %
  19. %                                                                             %
  20. %                                                                             %
  21. %  Copyright 1994 E. I. du Pont de Nemours & Company                          %
  22. %                                                                             %
  23. %  Permission to use, copy, modify, distribute, and sell this software and    %
  24. %  its documentation for any purpose is hereby granted without fee,           %
  25. %  provided that the above Copyright notice appear in all copies and that     %
  26. %  both that Copyright notice and this permission notice appear in            %
  27. %  supporting documentation, and that the name of E. I. du Pont de Nemours    %
  28. %  & Company not be used in advertising or publicity pertaining to            %
  29. %  distribution of the software without specific, written prior               %
  30. %  permission.  E. I. du Pont de Nemours & Company makes no representations   %
  31. %  about the suitability of this software for any purpose.  It is provided    %
  32. %  "as is" without express or implied warranty.                               %
  33. %                                                                             %
  34. %  E. I. du Pont de Nemours & Company disclaims all warranties with regard    %
  35. %  to this software, including all implied warranties of merchantability      %
  36. %  and fitness, in no event shall E. I. du Pont de Nemours & Company be       %
  37. %  liable for any special, indirect or consequential damages or any           %
  38. %  damages whatsoever resulting from loss of use, data or profits, whether    %
  39. %  in an action of contract, negligence or other tortuous action, arising     %
  40. %  out of or in connection with the use or performance of this software.      %
  41. %                                                                             %
  42. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  43. %
  44. %
  45. */
  46.  
  47. /*
  48.   Include declarations.
  49. */
  50. #include "magick.h"
  51. #include "image.h"
  52. #include "utility.h"
  53. #include "X.h"
  54.  
  55. /*
  56.   State declarations.
  57. */
  58. #define ControlState  0x0001
  59. #define DefaultState  0x0000
  60. #define ExitState  0x0002
  61.  
  62. /*
  63.   Forward declarations.
  64. */
  65. int
  66.   Latin1Compare _Declare((char *,char *));
  67.  
  68. static char
  69.   *XGetResourceInstance _Declare((XrmDatabase,char *,char *,char *));
  70.  
  71. static void
  72.   XMakeImageLSBFirst _Declare((XWindowInfo *,Image *, XImage *)),
  73.   XMakeImageMSBFirst _Declare((XWindowInfo *,Image *, XImage *));
  74.  
  75. static Window
  76.   XWindowByProperty _Declare((Display *,Window,Atom));
  77.  
  78. /*
  79. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  80. %                                                                             %
  81. %                                                                             %
  82. %                                                                             %
  83. %   I s T r u e                                                               %
  84. %                                                                             %
  85. %                                                                             %
  86. %                                                                             %
  87. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  88. %
  89. %  Function IsTrue returns True if the boolean is "true", "on", "yes" or "1".
  90. %
  91. %  The format of the IsTrue routine is:
  92. %
  93. %      option=IsTrue(boolean)
  94. %
  95. %  A description of each parameter follows:
  96. %
  97. %    o option: either True or False depending on the boolean parameter.
  98. %
  99. %    o boolean: Specifies a pointer to a character array.
  100. %
  101. %
  102. */
  103. unsigned int IsTrue(boolean)
  104. char
  105.   *boolean;
  106. {
  107.   if (boolean == (char *) NULL)
  108.     return(False);
  109.   if (Latin1Compare(boolean,"true") == 0)
  110.     return(True);
  111.   if (Latin1Compare(boolean,"on") == 0)
  112.     return(True);
  113.   if (Latin1Compare(boolean,"yes") == 0)
  114.     return(True);
  115.   if (Latin1Compare(boolean,"1") == 0)
  116.     return(True);
  117.   return(False);
  118. }
  119.  
  120. /*
  121. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  122. %                                                                             %
  123. %                                                                             %
  124. %                                                                             %
  125. %   L a t i n 1 C o m p a r e                                                 %
  126. %                                                                             %
  127. %                                                                             %
  128. %                                                                             %
  129. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  130. %
  131. %  Function Latin1Compare compares two null terminated Latin-1 strings,
  132. %  ignoring case differences, and returns an integer greater than, equal
  133. %  to, or less than 0, according to whether first is lexicographically
  134. %  greater than, equal to, or less than second.  The two strings are
  135. %  assumed to be encoded using ISO 8859-1.
  136. %
  137. %  The format of the Latin1Compare routine is:
  138. %
  139. %      Latin1Compare(first,second)
  140. %
  141. %  A description of each parameter follows:
  142. %
  143. %    o first: A pointer to the string to convert to Latin1 string.
  144. %
  145. %    o second: A pointer to the string to convert to Latin1 string.
  146. %
  147. %
  148. */
  149. int Latin1Compare(first,second)
  150. char
  151.   *first,
  152.   *second;
  153. {
  154.   register unsigned char
  155.    *p,
  156.    *q;
  157.  
  158.   p=(unsigned char *) first;
  159.   q=(unsigned char *) second;
  160.   while ((*p != '\0') && (*q != '\0'))
  161.   {
  162.     register unsigned char
  163.       c,
  164.       d;
  165.  
  166.     c=(*p);
  167.     d=(*q);
  168.     if (c != d)
  169.       {
  170.         /*
  171.           Try lowercasing and try again.
  172.         */
  173.         if ((c >= XK_A) && (c <= XK_Z))
  174.           c+=(XK_a-XK_A);
  175.         else
  176.           if ((c >= XK_Agrave) && (c <= XK_Odiaeresis))
  177.             c+=(XK_agrave-XK_Agrave);
  178.           else
  179.             if ((c >= XK_Ooblique) && (c <= XK_Thorn))
  180.               c+=(XK_oslash-XK_Ooblique);
  181.         if ((d >= XK_A) && (d <= XK_Z))
  182.           d+=(XK_a-XK_A);
  183.         else
  184.           if ((d >= XK_Agrave) && (d <= XK_Odiaeresis))
  185.             d+=(XK_agrave-XK_Agrave);
  186.           else if ((d >= XK_Ooblique) && (d <= XK_Thorn))
  187.             d+=(XK_oslash-XK_Ooblique);
  188.         if (c != d)
  189.           return(((int) c)-((int) d));
  190.       }
  191.     p++;
  192.     q++;
  193.   }
  194.   return(((int) *p)-((int) *q));
  195. }
  196.  
  197. /*
  198. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  199. %                                                                             %
  200. %                                                                             %
  201. %                                                                             %
  202. %   L a t i n 1 U p p e r                                                     %
  203. %                                                                             %
  204. %                                                                             %
  205. %                                                                             %
  206. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  207. %
  208. %  Function Latin1Upper copies a null terminated string from source to
  209. %  destination (including the null), changing all Latin-1 lowercase letters
  210. %  to uppercase.  The string is assumed to be encoded using ISO 8859-1.
  211. %
  212. %  The format of the Latin1Upper routine is:
  213. %
  214. %      Latin1Upper(string)
  215. %
  216. %  A description of each parameter follows:
  217. %
  218. %    o string: A pointer to the string to convert to upper-case Latin1.
  219. %
  220. %
  221. */
  222. static void Latin1Upper(string)
  223. char
  224.   *string;
  225. {
  226.   unsigned char
  227.     c;
  228.  
  229.   c=(*string);
  230.   while (c != '\0')
  231.   {
  232.     if ((c >= XK_a) && (c <= XK_z))
  233.       *string=c-(XK_a-XK_A);
  234.     else
  235.       if ((c >= XK_agrave) && (c <= XK_odiaeresis))
  236.         *string=c-(XK_agrave-XK_Agrave);
  237.       else
  238.         if ((c >= XK_oslash) && (c <= XK_thorn))
  239.           *string=c-(XK_oslash-XK_Ooblique);
  240.     string++;
  241.     c=(*string);
  242.   }
  243. }
  244.  
  245. /*
  246. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  247. %                                                                             %
  248. %                                                                             %
  249. %                                                                             %
  250. %   X A n n o t a t e I m a g e                                               %
  251. %                                                                             %
  252. %                                                                             %
  253. %                                                                             %
  254. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  255. %
  256. %  Function XAnnotateImage annotates the image with text.
  257. %
  258. %  The format of the XAnnotateImage routine is:
  259. %
  260. %    status=XAnnotateImage(display,pixel_info,annotate_info,background,image)
  261. %
  262. %  A description of each parameter follows:
  263. %
  264. %    o status: Function XAnnotateImage returns True if the image is
  265. %      successfully annotated with text.  False is returned is there is a
  266. %      memory shortage.
  267. %
  268. %    o display: Specifies a connection to an X server;  returned from
  269. %      XOpenDisplay.
  270. %
  271. %    o pixel_info: Specifies a pointer to a XPixelInfo structure.
  272. %
  273. %    o annotate_info: Specifies a pointer to a XAnnotateInfo structure.
  274. %
  275. %    o background: Specifies whether the background color is included in
  276. %      the annotation.  Must be either True or False;
  277. %
  278. %    o image: Specifies a pointer to a Image structure;  returned from
  279. %      ReadImage.
  280. %
  281. %
  282. */
  283. unsigned int XAnnotateImage(display,pixel_info,annotate_info,background,image)
  284. Display
  285.   *display;
  286.  
  287. XPixelInfo
  288.   *pixel_info;
  289.  
  290. XAnnotateInfo
  291.   *annotate_info;
  292.  
  293. unsigned int
  294.   background;
  295.  
  296. Image
  297.   *image;
  298. {
  299.   GC
  300.     annotate_context;
  301.  
  302.   Image
  303.     *annotate_image;
  304.  
  305.   int
  306.     x,
  307.     y;
  308.  
  309.   Pixmap
  310.     annotate_pixmap;
  311.  
  312.   register RunlengthPacket
  313.     *p,
  314.     *q;
  315.  
  316.   unsigned int
  317.     depth,
  318.     height,
  319.     width;
  320.  
  321.   Window
  322.     root_window;
  323.  
  324.   XGCValues
  325.     context_values;
  326.  
  327.   XImage
  328.     *annotate_ximage;
  329.  
  330.   /*
  331.     Initialize annotated image.
  332.   */
  333.   if (!UncompressImage(image))
  334.     return(False);
  335.   /*
  336.     Initialize annotated pixmap.
  337.   */
  338.   root_window=XRootWindow(display,XDefaultScreen(display));
  339.   depth=XDefaultDepth(display,XDefaultScreen(display));
  340.   annotate_pixmap=XCreatePixmap(display,root_window,annotate_info->width,
  341.     annotate_info->height,(int) depth);
  342.   if (annotate_pixmap == (Pixmap) NULL)
  343.     return(False);
  344.   /*
  345.     Initialize graphics info.
  346.   */
  347.   context_values.background=0;
  348.   context_values.foreground=(unsigned long) (~0);
  349.   context_values.font=annotate_info->font_info->fid;
  350.   annotate_context=XCreateGC(display,root_window,GCBackground | GCFont |
  351.     GCForeground,&context_values);
  352.   if (annotate_context == (GC) NULL)
  353.     return(False);
  354.   /*
  355.     Draw text to pixmap.
  356.   */
  357.   XDrawImageString(display,annotate_pixmap,annotate_context,0,
  358.     (int) annotate_info->font_info->ascent,annotate_info->text,
  359.     strlen(annotate_info->text));
  360.   XFreeGC(display,annotate_context);
  361.   /*
  362.     Initialize annotated X image.
  363.   */
  364.   annotate_ximage=XGetImage(display,annotate_pixmap,0,0,annotate_info->width,
  365.     annotate_info->height,AllPlanes,ZPixmap);
  366.   if (annotate_ximage == (XImage *) NULL)
  367.     return(False);
  368.   XFreePixmap(display,annotate_pixmap);
  369.   /*
  370.     Initialize annotated image.
  371.   */
  372.   annotate_image=AllocateImage((ImageInfo *) NULL);
  373.   if (annotate_image == (Image *) NULL)
  374.     return(False);
  375.   annotate_image->columns=annotate_info->width;
  376.   annotate_image->rows=annotate_info->height;
  377.   annotate_image->packets=annotate_image->columns*annotate_image->rows;
  378.   annotate_image->pixels=(RunlengthPacket *)
  379.     malloc((unsigned int) image->packets*sizeof(RunlengthPacket));
  380.   if (annotate_image->pixels == (RunlengthPacket *) NULL)
  381.     {
  382.       DestroyImage(annotate_image);
  383.       return(False);
  384.     }
  385.   /*
  386.     Transfer annotated X image to image.
  387.   */
  388.   q=annotate_image->pixels;
  389.   for (y=0; y < annotate_image->rows; y++)
  390.     for (x=0; x < annotate_image->columns; x++)
  391.     {
  392.       q->index=(unsigned short) XGetPixel(annotate_ximage,x,y);
  393.       if (q->index == 0)
  394.         {
  395.           /*
  396.             Set this pixel to the background color.
  397.           */
  398.           q->red=pixel_info->background_color.red >> 8;
  399.           q->green=pixel_info->background_color.green >> 8;
  400.           q->blue=pixel_info->background_color.blue >> 8;
  401.         }
  402.       else
  403.         {
  404.           /*
  405.             Set this pixel to the pen color.
  406.           */
  407.           q->red=pixel_info->annotate_color.red >> 8;
  408.           q->green=pixel_info->annotate_color.green >> 8;
  409.           q->blue=pixel_info->annotate_color.blue >> 8;
  410.         }
  411.       q->length=0;
  412.       q++;
  413.     }
  414.   XDestroyImage(annotate_ximage);
  415.   /*
  416.     Determine annotate geometry.
  417.   */
  418.   (void) XParseGeometry(annotate_info->geometry,&x,&y,&width,&height);
  419.   if ((width != annotate_image->columns) || (height != annotate_image->rows))
  420.     TransformImage(&annotate_image,(char *) NULL,annotate_info->geometry);
  421.   if (annotate_info->degrees != 0.0)
  422.     {
  423.       Image
  424.         *rotated_image;
  425.  
  426.       /*
  427.         Rotate image.
  428.       */
  429.       rotated_image=RotateImage(annotate_image,annotate_info->degrees,False);
  430.       if (rotated_image == (Image *) NULL)
  431.         return(False);
  432.       DestroyImage(annotate_image);
  433.       annotate_image=rotated_image;
  434.     }
  435.   /*
  436.     Paste annotated image to image.
  437.   */
  438.   image->class=DirectClass;
  439.   p=annotate_image->pixels;
  440.   q=image->pixels+y*image->columns+x;
  441.   for (y=0; y < annotate_image->rows; y++)
  442.   {
  443.     for (x=0; x < annotate_image->columns; x++)
  444.     {
  445.       if (p->index != 0)
  446.         {
  447.           /*
  448.             Set this pixel to the pen color.
  449.           */
  450.           *q=(*p);
  451.           q->index=pixel_info->annotate_index;
  452.         }
  453.       else
  454.         if (background)
  455.           {
  456.             /*
  457.               Set this pixel to the background color.
  458.             */
  459.             *q=(*p);
  460.             q->index=pixel_info->background_index;
  461.           }
  462.       p++;
  463.       q++;
  464.     }
  465.     q+=image->columns-annotate_image->columns;
  466.   }
  467.   DestroyImage(annotate_image);
  468.   return(True);
  469. }
  470.  
  471. /*
  472. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  473. %                                                                             %
  474. %                                                                             %
  475. %                                                                             %
  476. %   X B e s t F o n t                                                         %
  477. %                                                                             %
  478. %                                                                             %
  479. %                                                                             %
  480. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  481. %
  482. %  Function XBestFont returns the "best" font.  "Best" is defined as a font
  483. %  specified in the X resource database or a font such that the text width
  484. %  displayed with the font does not exceed the specified maximum width.
  485. %
  486. %  The format of the XBestFont routine is:
  487. %
  488. %      font=XBestFont(display,resource_info)
  489. %
  490. %  A description of each parameter follows:
  491. %
  492. %    o font: XBestFont returns a pointer to a XFontStruct structure.
  493. %
  494. %    o display: Specifies a connection to an X server;  returned from
  495. %      XOpenDisplay.
  496. %
  497. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  498. %
  499. %
  500. */
  501. XFontStruct *XBestFont(display,resource_info)
  502. Display
  503.   *display;
  504.  
  505. XResourceInfo
  506.   *resource_info;
  507. {
  508.   static char
  509.     *fonts[]=
  510.     {
  511.       "-adobe-helvetica-medium-r-normal--14-100-100-100-p-76-iso8859-1",
  512.       "-*-helvetica-medium-r-*-*-14-*",
  513.       "-*-lucida-medium-r-*-*-14-*",
  514.       "8x13",
  515.       "6x13",
  516.       "fixed",
  517.       "variable",
  518.       (char *) NULL
  519.     };
  520.  
  521.   char
  522.     **p;
  523.  
  524.   XFontStruct
  525.     *font_info;
  526.  
  527.   font_info=(XFontStruct *) NULL;
  528.   if (resource_info->font != (char *) NULL)
  529.     {
  530.       /*
  531.         Load preferred font specified in the X resource database.
  532.       */
  533.       font_info=XLoadQueryFont(display,resource_info->font);
  534.       if (font_info == (XFontStruct *) NULL)
  535.         Warning("Unable to load font",resource_info->font);
  536.     }
  537.   /*
  538.     Load fonts from list of fonts until one is found.
  539.   */
  540.   for (p=fonts; *p != (char *) NULL; p++)
  541.   {
  542.     if (font_info != (XFontStruct *) NULL)
  543.       break;
  544.     font_info=XLoadQueryFont(display,*p);
  545.   }
  546.   return(font_info);
  547. }
  548.  
  549. /*
  550. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  551. %                                                                             %
  552. %                                                                             %
  553. %                                                                             %
  554. %   X B e s t I c o n S i z e                                                 %
  555. %                                                                             %
  556. %                                                                             %
  557. %                                                                             %
  558. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  559. %
  560. %  Function XBestIconSize returns the "best" icon size.  "Best" is defined as
  561. %  an icon size that maintains the aspect ratio of the image.  If the window
  562. %  manager has preferred icon sizes, one of the preferred sizes is used.
  563. %
  564. %  The format of the XBestIconSize routine is:
  565. %
  566. %      XBestIconSize(display,window,image)
  567. %
  568. %  A description of each parameter follows:
  569. %
  570. %    o display: Specifies a connection to an X server;  returned from
  571. %      XOpenDisplay.
  572. %
  573. %    o image: Specifies a pointer to a Image structure;  returned from
  574. %      ReadImage.
  575. %
  576. %
  577. */
  578. void XBestIconSize(display,window,image)
  579. Display
  580.   *display;
  581.  
  582. XWindowInfo
  583.   *window;
  584.  
  585. Image
  586.   *image;
  587. {
  588. #define MaxIconSize  96
  589.  
  590.   int
  591.     i,
  592.     number_sizes;
  593.  
  594.   unsigned int
  595.     height,
  596.     icon_height,
  597.     icon_width,
  598.     width;
  599.  
  600.   unsigned long
  601.     scale_factor;
  602.  
  603.   Window
  604.     root_window;
  605.  
  606.   XIconSize
  607.     *icon_size,
  608.     *size_list;
  609.  
  610.   /*
  611.     Determine if the window manager has specified preferred icon sizes.
  612.   */
  613.   window->width=MaxIconSize;
  614.   window->height=MaxIconSize;
  615.   icon_size=(XIconSize *) NULL;
  616.   number_sizes=0;
  617.   root_window=XRootWindow(display,window->screen);
  618.   if (XGetIconSizes(display,root_window,&size_list,&number_sizes) != 0)
  619.     if ((number_sizes > 0) && (size_list != (XIconSize *) NULL))
  620.       icon_size=size_list;
  621.   if (icon_size == (XIconSize *) NULL)
  622.     {
  623.       /*
  624.         Window manager does not restrict icon size.
  625.       */
  626.       icon_size=XAllocIconSize();
  627.       if (icon_size == (XIconSize *) NULL)
  628.         {
  629.           Warning("Unable to choose best icon size","Memory allocation failed");
  630.           return;
  631.         }
  632.       icon_size->min_width=1;
  633.       icon_size->max_width=MaxIconSize;
  634.       icon_size->min_height=1;
  635.       icon_size->max_height=MaxIconSize;
  636.       icon_size->width_inc=1;
  637.       icon_size->height_inc=1;
  638.     }
  639.   /*
  640.     Determine aspect ratio of image.
  641.   */
  642.   width=image->columns;
  643.   height=image->rows;
  644.   if (window->clip_geometry)
  645.     (void) XParseGeometry(window->clip_geometry,&i,&i,&width,&height);
  646.   /*
  647.     Look for an icon size that maintains the aspect ratio of image.
  648.   */
  649.   scale_factor=UpShift(icon_size->max_width)/width;
  650.   if (scale_factor > (UpShift(icon_size->max_height)/height))
  651.     scale_factor=UpShift(icon_size->max_height)/height;
  652.   icon_width=icon_size->min_width;
  653.   while (icon_width < icon_size->max_width)
  654.   {
  655.     if (icon_width >= (DownShift(width*scale_factor)))
  656.       break;
  657.     icon_width+=icon_size->width_inc;
  658.   }
  659.   icon_height=icon_size->min_height;
  660.   while (icon_height < icon_size->max_height)
  661.   {
  662.     if (icon_height >= (DownShift(height*scale_factor)))
  663.       break;
  664.     icon_height+=icon_size->height_inc;
  665.   }
  666.   XFree((void *) icon_size);
  667.   window->width=icon_width;
  668.   window->height=icon_height;
  669. }
  670.  
  671. /*
  672. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  673. %                                                                             %
  674. %                                                                             %
  675. %                                                                             %
  676. %   X B e s t P i x e l                                                       %
  677. %                                                                             %
  678. %                                                                             %
  679. %                                                                             %
  680. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  681. %
  682. %  Function XBestPixel returns a pixel from an array of pixels that is closest
  683. %  to the requested color.  If the color array is NULL, the colors are obtained
  684. %  from the X server.
  685. %
  686. %  The format of the XBestPixel routine is:
  687. %
  688. %      pixel=XBestPixel(display,colormap,colors,number_colors,color)
  689. %
  690. %  A description of each parameter follows:
  691. %
  692. %    o pixel: XBestPixel returns the pixel value closest to the requested
  693. %      color.
  694. %
  695. %    o display: Specifies a connection to an X server;  returned from
  696. %      XOpenDisplay.
  697. %
  698. %    o colormap: Specifies the ID of the X server colormap.
  699. %
  700. %    o colors: Specifies an array of XColor structures.
  701. %
  702. %    o number_colors: Specifies the number of XColor structures in the
  703. %      color definition array.
  704. %
  705. %    o color: Specifies the desired RGB value to find in the colors array.
  706. %
  707. %
  708. */
  709. void XBestPixel(display,colormap,colors,number_colors,color)
  710. Display
  711.   *display;
  712.  
  713. Colormap
  714.   colormap;
  715.  
  716. XColor
  717.   *colors;
  718.  
  719. unsigned int
  720.   number_colors;
  721.  
  722. XColor
  723.   *color;
  724. {
  725.   int
  726.     query_server,
  727.     status;
  728.  
  729.   register int
  730.     blue_distance,
  731.     green_distance,
  732.     i,
  733.     red_distance;
  734.  
  735.   unsigned long
  736.     distance,
  737.     min_distance;
  738.  
  739.   /*
  740.     Find closest representation for the requested RGB color.
  741.   */
  742.   status=XAllocColor(display,colormap,color);
  743.   if (status != 0)
  744.     return;
  745.   query_server=colors == (XColor *) NULL;
  746.   if (query_server)
  747.     {
  748.       /*
  749.         Read X server colormap.
  750.       */
  751.       colors=(XColor *) malloc(number_colors*sizeof(XColor));
  752.       if (colors == (XColor *) NULL)
  753.         Error("Unable to read X server colormap","Memory allocation failed");
  754.       for (i=0; i < number_colors; i++)
  755.         colors[i].pixel=(unsigned long) i;
  756.       if (number_colors > 256)
  757.         number_colors=256;
  758.       XQueryColors(display,colormap,colors,number_colors);
  759.     }
  760.   color->pixel=0;
  761.   min_distance=(unsigned long) (~0);
  762.   for (i=0; i < number_colors; i++)
  763.   {
  764.     red_distance=(int) (colors[i].red >> 8)-(int) (color->red >> 8);
  765.     green_distance=(int) (colors[i].green >> 8)-(int) (color->green >> 8);
  766.     blue_distance=(int) (colors[i].blue >> 8)-(int) (color->blue >> 8);
  767.     distance=red_distance*red_distance+green_distance*green_distance+
  768.       blue_distance*blue_distance;
  769.     if (distance < min_distance)
  770.       {
  771.         min_distance=distance;
  772.         color->pixel=colors[i].pixel;
  773.       }
  774.   }
  775.   if (query_server)
  776.     (void) free((char *) colors);
  777. }
  778.  
  779. /*
  780. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  781. %                                                                             %
  782. %                                                                             %
  783. %                                                                             %
  784. %   X B e s t V i s u a l I n f o                                             %
  785. %                                                                             %
  786. %                                                                             %
  787. %                                                                             %
  788. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  789. %
  790. %  Function XBestVisualInfo returns visual information for a visual that is
  791. %  the "best" the server supports.  "Best" is defined as:
  792. %
  793. %    1. Restrict the visual list to those supported by the default screen.
  794. %
  795. %    2. If a visual type is specified, restrict the visual list to those of
  796. %       that type.
  797. %
  798. %    3. If a map type is specified, choose the visual that matches the id
  799. %       specified by the Standard Colormap.
  800. %
  801. %    4  From the list of visuals, choose one that can display the most
  802. %       simultaneous colors.  If more than one visual can display the same
  803. %       number of simultaneous colors, one is choosen based on a rank.
  804. %
  805. %  The format of the XBestVisualInfo routine is:
  806. %
  807. %      visual_info=XBestVisualInfo(display,map_info,resource_info)
  808. %
  809. %  A description of each parameter follows:
  810. %
  811. %    o visual_info: XBestVisualInfo returns a pointer to a X11 XVisualInfo
  812. %      structure.
  813. %
  814. %    o display: Specifies a connection to an X server;  returned from
  815. %      XOpenDisplay.
  816. %
  817. %    o map_info: If map_type is specified, this structure is initialized
  818. %      with info from the Standard Colormap.
  819. %
  820. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  821. %
  822. %
  823. */
  824. XVisualInfo *XBestVisualInfo(display,map_info,resource_info)
  825. Display
  826.   *display;
  827.  
  828. XStandardColormap
  829.   *map_info;
  830.  
  831. XResourceInfo
  832.   *resource_info;
  833. {
  834. #define XVisualColormapSize(visual_info) \
  835.   ((visual_info->class == TrueColor) || (visual_info->class == DirectColor) ? \
  836.     visual_info->red_mask | visual_info->green_mask | visual_info->blue_mask : \
  837.     visual_info->colormap_size)
  838.  
  839.   char
  840.     *map_type,
  841.     *visual_type;
  842.  
  843.   int
  844.     number_visuals;
  845.  
  846.   register int
  847.     i;
  848.  
  849.   unsigned int
  850.     visual_mask;
  851.  
  852.   XVisualInfo
  853.     *visual_info,
  854.     *visual_list,
  855.     visual_template;
  856.  
  857.   /*
  858.     Restrict visual search by screen number.
  859.   */
  860.   map_type=resource_info->map_type;
  861.   visual_type=resource_info->visual_type;
  862.   visual_mask=VisualScreenMask;
  863.   visual_template.screen=XDefaultScreen(display);
  864.   if (visual_type != (char *) NULL)
  865.     {
  866.       /*
  867.         Restrict visual search by class or visual id.
  868.       */
  869.       if (Latin1Compare("staticgray",visual_type) == 0)
  870.         {
  871.           visual_mask|=VisualClassMask;
  872.           visual_template.class=StaticGray;
  873.         }
  874.       else
  875.         if (Latin1Compare("grayscale",visual_type) == 0)
  876.           {
  877.             visual_mask|=VisualClassMask;
  878.             visual_template.class=GrayScale;
  879.           }
  880.         else
  881.           if (Latin1Compare("staticcolor",visual_type) == 0)
  882.             {
  883.               visual_mask|=VisualClassMask;
  884.               visual_template.class=StaticColor;
  885.             }
  886.           else
  887.             if (Latin1Compare("pseudocolor",visual_type) == 0)
  888.               {
  889.                 visual_mask|=VisualClassMask;
  890.                 visual_template.class=PseudoColor;
  891.               }
  892.             else
  893.               if (Latin1Compare("truecolor",visual_type) == 0)
  894.                 {
  895.                   visual_mask|=VisualClassMask;
  896.                   visual_template.class=TrueColor;
  897.                 }
  898.               else
  899.                 if (Latin1Compare("directcolor",visual_type) == 0)
  900.                   {
  901.                     visual_mask|=VisualClassMask;
  902.                     visual_template.class=DirectColor;
  903.                   }
  904.                 else
  905.                   if (Latin1Compare("default",visual_type) == 0)
  906.                     {
  907.                       visual_mask|=VisualIDMask;
  908.                       visual_template.visualid=XVisualIDFromVisual(
  909.                         XDefaultVisual(display,XDefaultScreen(display)));
  910.                     }
  911.                   else
  912.                     if (isdigit(*visual_type))
  913.                       {
  914.                         visual_mask|=VisualIDMask;
  915.                         visual_template.visualid=
  916.                           strtol(visual_type,(char **) NULL,0);
  917.                       }
  918.                     else
  919.                       Warning("Invalid visual specifier",visual_type);
  920.     }
  921.   /*
  922.     Get all visuals that meet our criteria so far.
  923.   */
  924.   number_visuals=0;
  925.   visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
  926.     &number_visuals);
  927.   visual_mask=VisualScreenMask | VisualIDMask;
  928.   if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
  929.     {
  930.       /*
  931.         Failed to get visual;  try using the default visual.
  932.       */
  933.       Warning("Unable to get visual",visual_type);
  934.       visual_template.visualid=
  935.         XVisualIDFromVisual(XDefaultVisual(display,XDefaultScreen(display)));
  936.       visual_list=XGetVisualInfo(display,visual_mask,&visual_template,
  937.         &number_visuals);
  938.       if ((number_visuals == 0) || (visual_list == (XVisualInfo *) NULL))
  939.         return((XVisualInfo *) NULL);
  940.       Warning("Using default visual",XVisualClassName(visual_list->class));
  941.     }
  942.   if (map_type != (char *) NULL)
  943.     {
  944.       Atom
  945.         map_property;
  946.  
  947.       char
  948.         map_name[MaxTextLength];
  949.  
  950.       int
  951.         j,
  952.         number_maps,
  953.         status;
  954.  
  955.       Window
  956.         root_window;
  957.  
  958.       XStandardColormap
  959.         *map_list;
  960.  
  961.       /*
  962.         Restrict visual search by Standard Colormap visual id.
  963.       */
  964.       (void) sprintf((char *) map_name,"RGB_%s_MAP",map_type);
  965.       Latin1Upper(map_name);
  966.       map_property=XInternAtom(display,(char *) map_name,True);
  967.       if (map_property == (Atom) NULL)
  968.         Error("Unable to get Standard Colormap",map_type);
  969.       root_window=XRootWindow(display,XDefaultScreen(display));
  970.       status=XGetRGBColormaps(display,root_window,&map_list,&number_maps,
  971.         map_property);
  972.       if (status == 0)
  973.         Error("Unable to get Standard Colormap",map_type);
  974.       /*
  975.         Search all Standard Colormaps and visuals for ids that match.
  976.       */
  977.       *map_info=map_list[0];
  978. #ifndef PRE_R4_ICCCM
  979.       visual_template.visualid=XVisualIDFromVisual(visual_list[0].visual);
  980.       for (i=0; i < number_maps; i++)
  981.         for (j=0; j < number_visuals; j++)
  982.           if (map_list[i].visualid ==
  983.               XVisualIDFromVisual(visual_list[j].visual))
  984.             {
  985.               *map_info=map_list[i];
  986.               visual_template.visualid=
  987.                 XVisualIDFromVisual(visual_list[j].visual);
  988.               break;
  989.             }
  990.       if (map_info->visualid != visual_template.visualid)
  991.         Error("Unable to match visual to Standard Colormap",map_type);
  992. #endif
  993.       if (map_info->colormap == (Colormap) NULL)
  994.         Error("Standard Colormap is not initialized",map_type);
  995.       XFree((void *) map_list);
  996.     }
  997.   else
  998.     {
  999.       static unsigned int
  1000.         rank[]=
  1001.           {
  1002.             StaticGray,
  1003.             GrayScale,
  1004.             StaticColor,
  1005.             DirectColor,
  1006.             TrueColor,
  1007.             PseudoColor
  1008.           };
  1009.  
  1010.       XVisualInfo
  1011.         *p;
  1012.  
  1013.       /*
  1014.         Pick one visual that displays the most simultaneous colors.
  1015.       */
  1016.       visual_info=visual_list;
  1017.       p=visual_list;
  1018.       for (i=1; i < number_visuals; i++)
  1019.       {
  1020.         p++;
  1021.         if (XVisualColormapSize(p) > XVisualColormapSize(visual_info))
  1022.           visual_info=p;
  1023.         else
  1024.           if (XVisualColormapSize(p) == XVisualColormapSize(visual_info))
  1025.             if (rank[p->class] > rank[visual_info->class])
  1026.               visual_info=p;
  1027.       }
  1028.       visual_template.visualid=XVisualIDFromVisual(visual_info->visual);
  1029.     }
  1030.   XFree((void *) visual_list);
  1031.   /*
  1032.     Retrieve only one visual by its screen & id number.
  1033.   */
  1034.   visual_info=XGetVisualInfo(display,visual_mask,&visual_template,
  1035.     &number_visuals);
  1036.   if ((number_visuals == 0) || (visual_info == (XVisualInfo *) NULL))
  1037.     return((XVisualInfo *) NULL);
  1038.   return(visual_info);
  1039. }
  1040.  
  1041. /*
  1042. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1043. %                                                                             %
  1044. %                                                                             %
  1045. %                                                                             %
  1046. %   X C l i e n t W i n d o w                                                 %
  1047. %                                                                             %
  1048. %                                                                             %
  1049. %                                                                             %
  1050. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1051. %
  1052. %  Function XClientWindow finds a window, at or below the specified window,
  1053. %  which has a WM_STATE property.  If such a window is found, it is returned,
  1054. %  otherwise the argument window is returned.
  1055. %
  1056. %  The format of the XClientWindow function is:
  1057. %
  1058. %      client_window=XClientWindow(display,target_window)
  1059. %
  1060. %  A description of each parameter follows:
  1061. %
  1062. %    o client_window: XClientWindow returns a window, at or below the specified
  1063. %      window, which has a WM_STATE property otherwise the argument
  1064. %      target_window is returned.
  1065. %
  1066. %    o display: Specifies a pointer to the Display structure;  returned from
  1067. %      XOpenDisplay.
  1068. %
  1069. %    o target_window: Specifies the window to find a WM_STATE property.
  1070. %
  1071. %
  1072. */
  1073. Window XClientWindow(display,target_window)
  1074. Display
  1075.   *display;
  1076.  
  1077. Window
  1078.   target_window;
  1079. {
  1080.   Atom
  1081.     state,
  1082.     type;
  1083.  
  1084.   int
  1085.     format,
  1086.     status;
  1087.  
  1088.   unsigned char
  1089.     *data;
  1090.  
  1091.   unsigned long
  1092.     after,
  1093.     number_items;
  1094.  
  1095.   Window
  1096.     client_window;
  1097.  
  1098.   state=XInternAtom(display,"WM_STATE",True);
  1099.   if (state == (Atom) NULL)
  1100.     return(target_window);
  1101.   type=(Atom) NULL;
  1102.   status=XGetWindowProperty(display,target_window,state,0L,0L,False,
  1103.     (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data);
  1104.   if ((status == Success) && (type != (Atom) NULL))
  1105.     return(target_window);
  1106.   client_window=XWindowByProperty(display,target_window,state);
  1107.   if (client_window == (Window) NULL)
  1108.     return(target_window);
  1109.   return(client_window);
  1110. }
  1111.  
  1112. /*
  1113. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1114. %                                                                             %
  1115. %                                                                             %
  1116. %                                                                             %
  1117. %   X D e l a y                                                               %
  1118. %                                                                             %
  1119. %                                                                             %
  1120. %                                                                             %
  1121. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1122. %
  1123. %  Function XDelay suspends program execution for the number of milliseconds
  1124. %  specified.
  1125. %
  1126. %  The format of the Delay routine is:
  1127. %
  1128. %      XDelay(display,milliseconds)
  1129. %
  1130. %  A description of each parameter follows:
  1131. %
  1132. %    o display: Specifies a pointer to the Display structure;  returned from
  1133. %      XOpenDisplay.
  1134. %
  1135. %    o milliseconds: Specifies the number of milliseconds to delay before
  1136. %      returning.
  1137. %
  1138. %
  1139. */
  1140. void XDelay(display,milliseconds)
  1141. Display
  1142.   *display;
  1143.  
  1144. unsigned long
  1145.   milliseconds;
  1146. {
  1147. #ifndef vms
  1148. #ifdef SYSV
  1149. #include <sys/poll.h>
  1150.  
  1151.   struct pollfd
  1152.     descriptor;
  1153.  
  1154.   if (milliseconds == 0)
  1155.     return;
  1156.   (void) XFlush(display);
  1157.   (void) poll((struct pollfd *) NULL,0,(int) milliseconds);
  1158. #else
  1159.   struct timeval
  1160.     timer;
  1161.  
  1162.   if (milliseconds == 0)
  1163.     return;
  1164.   (void) XFlush(display);
  1165.   timer.tv_sec=milliseconds/1000;
  1166.   timer.tv_usec=(milliseconds % 1000)*1000;
  1167. #ifdef __hpux
  1168.   (void) select(0,(int *) NULL,(int *) NULL,(int *) NULL,&timer);
  1169. #else
  1170.   (void) select(0,(fd_set *) NULL,(fd_set *) NULL,(fd_set *) NULL,&timer);
  1171. #endif
  1172. #endif
  1173. #endif
  1174. }
  1175.  
  1176. /*
  1177. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1178. %                                                                             %
  1179. %                                                                             %
  1180. %                                                                             %
  1181. %   X D i s p l a y I n f o S t r i n g                                       %
  1182. %                                                                             %
  1183. %                                                                             %
  1184. %                                                                             %
  1185. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1186. %
  1187. %  Function XDisplayInfoString first clears the info window and draws a
  1188. %  text string justifed left in the x-direction and centered within the
  1189. %  y-direction.
  1190. %
  1191. %  The format of the XDisplayInfoString function is:
  1192. %
  1193. %      XDisplayInfoString(display,window_info,text)
  1194. %
  1195. %  A description of each parameter follows:
  1196. %
  1197. %    o display: Specifies a pointer to the Display structure;  returned from
  1198. %      XOpenDisplay.
  1199. %
  1200. %    o window_info: Specifies a pointer to a XWindowInfo structure.
  1201. %
  1202. %    o text: Specifies a pointer to a text string.
  1203. %
  1204. %
  1205. */
  1206. void XDisplayInfoString(display,window_info,text)
  1207. Display
  1208.   *display;
  1209.  
  1210. XWindowInfo
  1211.   *window_info;
  1212.  
  1213. char
  1214.   *text;
  1215. {
  1216.   int
  1217.     length,
  1218.     x,
  1219.     y;
  1220.  
  1221.   unsigned int
  1222.     width;
  1223.  
  1224.   XFontStruct
  1225.     *font_info;
  1226.  
  1227.   /*
  1228.     Insure text will fit within the window.
  1229.   */
  1230.   font_info=window_info->font_info;
  1231.   width=window_info->width-font_info->max_bounds.width;
  1232.   for (length=strlen(text); length > 0; length--)
  1233.     if (XTextWidth(font_info,text,length) <= width)
  1234.       break;
  1235.   /*
  1236.     Clear the info window then draw the text.
  1237.   */
  1238.   XClearWindow(display,window_info->id);
  1239.   x=font_info->max_bounds.width >> 1;
  1240.   y=font_info->ascent+(window_info->height >> 3);
  1241.   XDrawString(display,window_info->id,window_info->annotate_context,x,y,
  1242.     text,length);
  1243. }
  1244.  
  1245. /*
  1246. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1247. %                                                                             %
  1248. %                                                                             %
  1249. %                                                                             %
  1250. %   X E r r o r                                                               %
  1251. %                                                                             %
  1252. %                                                                             %
  1253. %                                                                             %
  1254. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1255. %
  1256. %  Function XError ignores BadWindow errors for XQueryTree and
  1257. %  XGetWindowAttributes, and ignores BadDrawable errors for XGetGeometry, and
  1258. %  ignores BadValue errors for XQueryColor.  It returns False in those cases.
  1259. %  Otherwise it returns True.
  1260. %
  1261. %  The format of the XError function is:
  1262. %
  1263. %      XError(display,error)
  1264. %
  1265. %  A description of each parameter follows:
  1266. %
  1267. %    o display: Specifies a pointer to the Display structure;  returned from
  1268. %      XOpenDisplay.
  1269. %
  1270. %    o error: Specifies the error event.
  1271. %
  1272. %
  1273. */
  1274. int XError(display,error)
  1275. Display
  1276.   *display;
  1277.  
  1278. XErrorEvent
  1279.   *error;
  1280. {
  1281.   switch (error->request_code)
  1282.   {
  1283.     case X_GetGeometry:
  1284.     {
  1285.       if (error->error_code == BadDrawable)
  1286.         return(False);
  1287.       break;
  1288.     }
  1289.     case X_GetWindowAttributes:
  1290.     case X_QueryTree:
  1291.     {
  1292.       if (error->error_code == BadWindow)
  1293.         return(False);
  1294.       break;
  1295.     }
  1296.     case X_QueryColors:
  1297.     {
  1298.       if (error->error_code == BadValue)
  1299.         return(False);
  1300.       break;
  1301.     }
  1302.   }
  1303.   return(True);
  1304. }
  1305.  
  1306. /*
  1307. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1308. %                                                                             %
  1309. %                                                                             %
  1310. %                                                                             %
  1311. %   X F r e e R e s o u r c e s                                               %
  1312. %                                                                             %
  1313. %                                                                             %
  1314. %                                                                             %
  1315. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1316. %
  1317. %  Function XFreeResources frees X11 resources.
  1318. %
  1319. %  The format of the XFreeResources routine is:
  1320. %
  1321. %      XFreeResources(display,visual_info,map_info,pixel_info,font_info,
  1322. %        resource_info,window_info)
  1323. %
  1324. %  A description of each parameter follows:
  1325. %
  1326. %    o display: Specifies a connection to an X server; returned from
  1327. %      XOpenDisplay.
  1328. %
  1329. %    o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
  1330. %      returned from XGetVisualInfo.
  1331. %
  1332. %    o map_info: If map_type is specified, this structure is initialized
  1333. %      with info from the Standard Colormap.
  1334. %
  1335. %    o pixel_info: Specifies a pointer to a XPixelInfo structure.
  1336. %
  1337. %    o font_info: Specifies a pointer to a XFontStruct structure.
  1338. %
  1339. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  1340. %
  1341. %    o window_info: Specifies a pointer to a X11 XWindowInfo structure.
  1342. %
  1343. %
  1344. */
  1345. void XFreeResources(display,visual_info,map_info,pixel_info,font_info,
  1346.   resource_info,window_info)
  1347. Display
  1348.   *display;
  1349.  
  1350. XVisualInfo
  1351.   *visual_info;
  1352.  
  1353. XStandardColormap
  1354.   *map_info;
  1355.  
  1356. XPixelInfo
  1357.   *pixel_info;
  1358.  
  1359. XFontStruct
  1360.   *font_info;
  1361.  
  1362. XResourceInfo
  1363.   *resource_info;
  1364.  
  1365. XWindowInfo
  1366.   *window_info;
  1367. {
  1368.   if (window_info != (XWindowInfo *) NULL)
  1369.     {
  1370.       /*
  1371.         Free X image.
  1372.       */
  1373.       if (window_info->ximage != (XImage *) NULL)
  1374.         XDestroyImage(window_info->ximage);
  1375.       if (window_info->id != (Window) NULL)
  1376.         {
  1377.           /*
  1378.             Free destroy window and free cursors.
  1379.           */
  1380.           if (window_info->id != XRootWindow(display,visual_info->screen))
  1381.             XDestroyWindow(display,window_info->id);
  1382.           if (window_info->annotate_context != (GC) NULL)
  1383.             XFreeGC(display,window_info->annotate_context);
  1384.           if (window_info->highlight_context != (GC) NULL)
  1385.             XFreeGC(display,window_info->highlight_context);
  1386.           if (window_info->widget_context != (GC) NULL)
  1387.             XFreeGC(display,window_info->widget_context);
  1388.           XFreeCursor(display,window_info->cursor);
  1389.           XFreeCursor(display,window_info->busy_cursor);
  1390.         }
  1391.     }
  1392.   /*
  1393.     Free font.
  1394.   */
  1395.   if (font_info != (XFontStruct *) NULL)
  1396.     XFreeFont(display,font_info);
  1397.   if (map_info != (XStandardColormap *) NULL)
  1398.     {
  1399.       /*
  1400.         Free X Standard Colormap.
  1401.       */
  1402.       if (resource_info->map_type == (char *) NULL)
  1403.         XFreeStandardColormap(display,visual_info,map_info,pixel_info);
  1404.       XFree((void *) map_info);
  1405.     }
  1406.   /*
  1407.     Free X visual info.
  1408.   */
  1409.   if (visual_info != (XVisualInfo *) NULL)
  1410.     XFree((void *) visual_info);
  1411.   /*
  1412.     Free resource database.
  1413.   */
  1414.   if (resource_info->resource_database != (XrmDatabase) NULL)
  1415.     XrmDestroyDatabase(resource_info->resource_database);
  1416.   XCloseDisplay(display);
  1417. }
  1418.  
  1419. /*
  1420. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1421. %                                                                             %
  1422. %                                                                             %
  1423. %                                                                             %
  1424. %   X F r e e S t a n d a r d C o l o r m a p                                 %
  1425. %                                                                             %
  1426. %                                                                             %
  1427. %                                                                             %
  1428. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1429. %
  1430. %  Function XFreeStandardColormap frees an X11 colormap.
  1431. %
  1432. %  The format of the XFreeStandardColormap routine is:
  1433. %
  1434. %      XFreeStandardColormap(display,visual_info,map_info,pixel_info)
  1435. %
  1436. %  A description of each parameter follows:
  1437. %
  1438. %    o display: Specifies a connection to an X server; returned from
  1439. %      XOpenDisplay.
  1440. %
  1441. %    o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
  1442. %      returned from XGetVisualInfo.
  1443. %
  1444. %    o map_info: If map_type is specified, this structure is initialized
  1445. %      with info from the Standard Colormap.
  1446. %
  1447. %    o pixel_info: Specifies a pointer to a XPixelInfo structure.
  1448. %
  1449. %
  1450. */
  1451. void XFreeStandardColormap(display,visual_info,map_info,pixel_info)
  1452. Display
  1453.   *display;
  1454.  
  1455. XVisualInfo
  1456.   *visual_info;
  1457.  
  1458. XStandardColormap
  1459.   *map_info;
  1460.  
  1461. XPixelInfo
  1462.   *pixel_info;
  1463. {
  1464.   /*
  1465.     Free colormap.
  1466.   */
  1467.   XFlush(display);
  1468.   if (map_info->colormap != (Colormap) NULL)
  1469.     if (map_info->colormap != XDefaultColormap(display,visual_info->screen))
  1470.       XFreeColormap(display,map_info->colormap);
  1471.     else
  1472.       if (pixel_info != (XPixelInfo *) NULL)
  1473.         if ((visual_info->class != TrueColor) &&
  1474.             (visual_info->class != DirectColor))
  1475.           XFreeColors(display,map_info->colormap,pixel_info->pixels,
  1476.             (int) pixel_info->colors,0);
  1477.   map_info->colormap=(Colormap) NULL;
  1478.   if (pixel_info != (XPixelInfo *) NULL)
  1479.     {
  1480.       if (pixel_info->pixels != (unsigned long *) NULL)
  1481.         (void) free((char *) pixel_info->pixels);
  1482.       pixel_info->pixels=(unsigned long *) NULL;
  1483.     }
  1484. }
  1485.  
  1486. /*
  1487. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1488. %                                                                             %
  1489. %                                                                             %
  1490. %                                                                             %
  1491. %   X G e t A n n o t a t e I n f o                                           %
  1492. %                                                                             %
  1493. %                                                                             %
  1494. %                                                                             %
  1495. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1496. %
  1497. %  Function XGetAnnotateInfo initializes the AnnotateInfo structure.
  1498. %
  1499. %  The format of the GetAnnotateInfo routine is:
  1500. %
  1501. %      XGetAnnotateInfo(image_info)
  1502. %
  1503. %  A description of each parameter follows:
  1504. %
  1505. %    o annotate_info: Specifies a pointer to a XAnnotateInfo structure.
  1506. %
  1507. %
  1508. */
  1509. void XGetAnnotateInfo(annotate_info)
  1510. XAnnotateInfo
  1511.   *annotate_info;
  1512. {
  1513.   /*
  1514.     Initialize annotate structure.
  1515.   */
  1516.   annotate_info->x=0;
  1517.   annotate_info->y=0;
  1518.   annotate_info->width=0;
  1519.   annotate_info->height=0;
  1520.   annotate_info->degrees=0.0;
  1521.   annotate_info->font_info=(XFontStruct *) NULL;
  1522.   annotate_info->text=(char *) NULL;
  1523.   *annotate_info->geometry=(char) NULL;
  1524.   annotate_info->previous=(XAnnotateInfo *) NULL;
  1525.   annotate_info->next=(XAnnotateInfo *) NULL;
  1526. }
  1527.  
  1528. /*
  1529. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1530. %                                                                             %
  1531. %                                                                             %
  1532. %                                                                             %
  1533. %   X G e t M a p I n f o                                                     %
  1534. %                                                                             %
  1535. %                                                                             %
  1536. %                                                                             %
  1537. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1538. %
  1539. %  Function XGetMapInfo initializes the XStandardColormap structure.
  1540. %
  1541. %  The format of the XStandardColormap routine is:
  1542. %
  1543. %      XGetMapInfo(visual_info,colormap,map_info)
  1544. %
  1545. %  A description of each parameter follows:
  1546. %
  1547. %    o colormap: Specifies the ID of the X server colormap.
  1548. %
  1549. %    o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
  1550. %      returned from XGetVisualInfo.
  1551. %
  1552. %    o map_info: Specifies a pointer to a X11 XStandardColormap structure.
  1553. %
  1554. %
  1555. */
  1556. void XGetMapInfo(visual_info,colormap,map_info)
  1557. XVisualInfo
  1558.   *visual_info;
  1559.  
  1560. Colormap
  1561.   colormap;
  1562.  
  1563. XStandardColormap
  1564.   *map_info;
  1565. {
  1566.   /*
  1567.     Initialize map info.
  1568.   */
  1569.   map_info->colormap=colormap;
  1570.   map_info->red_max=visual_info->red_mask;
  1571.   map_info->red_mult=map_info->red_max > 0 ? 1 : 0;
  1572.   if (map_info->red_max > 0)
  1573.     while ((map_info->red_max & 0x01) == 0)
  1574.     {
  1575.       map_info->red_max>>=1;
  1576.       map_info->red_mult<<=1;
  1577.     }
  1578.   map_info->green_max=visual_info->green_mask;
  1579.   map_info->green_mult=map_info->green_max > 0 ? 1 : 0;
  1580.   if (map_info->green_max > 0)
  1581.     while ((map_info->green_max & 0x01) == 0)
  1582.     {
  1583.       map_info->green_max>>=1;
  1584.       map_info->green_mult<<=1;
  1585.     }
  1586.   map_info->blue_max=visual_info->blue_mask;
  1587.   map_info->blue_mult=map_info->blue_max > 0 ? 1 : 0;
  1588.   if (map_info->blue_max > 0)
  1589.     while ((map_info->blue_max & 0x01) == 0)
  1590.     {
  1591.       map_info->blue_max>>=1;
  1592.       map_info->blue_mult<<=1;
  1593.     }
  1594.   map_info->base_pixel=0;
  1595. }
  1596.  
  1597. /*
  1598. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1599. %                                                                             %
  1600. %                                                                             %
  1601. %                                                                             %
  1602. %   X G e t P i x e l I n f o                                                 %
  1603. %                                                                             %
  1604. %                                                                             %
  1605. %                                                                             %
  1606. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1607. %
  1608. %  Function XGetPixelInfo initializes the PixelInfo structure.
  1609. %
  1610. %  The format of the XGetPixelInfo routine is:
  1611. %
  1612. %      XGetPixelInfo(display,visual_info,map_info,resource_info,image,
  1613. %        pixel_info)
  1614. %
  1615. %  A description of each parameter follows:
  1616. %
  1617. %    o display: Specifies a connection to an X server; returned from
  1618. %      XOpenDisplay.
  1619. %
  1620. %    o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
  1621. %      returned from XGetVisualInfo.
  1622. %
  1623. %    o map_info: If map_type is specified, this structure is initialized
  1624. %      with info from the Standard Colormap.
  1625. %
  1626. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  1627. %
  1628. %    o image: Specifies a pointer to a Image structure;  returned from
  1629. %      ReadImage.
  1630. %
  1631. %    o pixel_info: Specifies a pointer to a XPixelInfo structure.
  1632. %
  1633. %
  1634. */
  1635. void XGetPixelInfo(display,visual_info,map_info,resource_info,image,pixel_info)
  1636. Display
  1637.   *display;
  1638.  
  1639. XVisualInfo
  1640.   *visual_info;
  1641.  
  1642. XStandardColormap
  1643.   *map_info;
  1644.  
  1645. XResourceInfo
  1646.   *resource_info;
  1647.  
  1648. Image
  1649.   *image;
  1650.  
  1651. XPixelInfo
  1652.   *pixel_info;
  1653. {
  1654.   static char
  1655.     *PenColors[MaxNumberPens]=
  1656.     {
  1657.       Pen1Color,
  1658.       Pen2Color,
  1659.       Pen3Color,
  1660.       Pen4Color,
  1661.       Pen5Color,
  1662.       Pen6Color,
  1663.       Pen7Color,
  1664.       Pen8Color,
  1665.       Pen9Color,
  1666.       Pen0Color,
  1667.     };
  1668.  
  1669.   Colormap
  1670.     colormap;
  1671.  
  1672.   int
  1673.     blue,
  1674.     green,
  1675.     red,
  1676.     status;
  1677.  
  1678.   register int
  1679.     i;
  1680.  
  1681.   unsigned int
  1682.     packets;
  1683.  
  1684.   /*
  1685.     Initialize pixel info.
  1686.   */
  1687.   pixel_info->colors=0;
  1688.   if (image != (Image *) NULL)
  1689.     if (image->class == PseudoClass)
  1690.       pixel_info->colors=image->colors;
  1691.   packets=Max(pixel_info->colors,visual_info->colormap_size)+MaxNumberPens;
  1692.   pixel_info->pixels=(unsigned long *) malloc(packets*sizeof(unsigned long));
  1693.   if (pixel_info->pixels == (unsigned long *) NULL)
  1694.     Error("Unable to get pixel info","Memory allocation failed");
  1695.   /*
  1696.     Set foreground color.
  1697.   */
  1698.   colormap=map_info->colormap;
  1699.   (void) XParseColor(display,colormap,ForegroundColor,
  1700.     &pixel_info->foreground_color);
  1701.   status=XParseColor(display,colormap,resource_info->foreground_color,
  1702.     &pixel_info->foreground_color);
  1703.   if (status == 0)
  1704.     Warning("Color is not known to X server",resource_info->foreground_color);
  1705.   pixel_info->foreground_color.pixel=
  1706.     XStandardPixel(map_info,pixel_info->foreground_color,16);
  1707.   pixel_info->foreground_color.flags=DoRed | DoGreen | DoBlue;
  1708.   /*
  1709.     Set background color.
  1710.   */
  1711.   (void) XParseColor(display,colormap,BackgroundColor,
  1712.     &pixel_info->background_color);
  1713.   status=XParseColor(display,colormap,resource_info->background_color,
  1714.     &pixel_info->background_color);
  1715.   if (status == 0)
  1716.     Warning("Color is not known to X server",resource_info->background_color);
  1717.   pixel_info->background_color.pixel=
  1718.     XStandardPixel(map_info,pixel_info->background_color,16);
  1719.   pixel_info->background_color.flags=DoRed | DoGreen | DoBlue;
  1720.   /*
  1721.     Set border color.
  1722.   */
  1723.   (void) XParseColor(display,colormap,BorderColor,&pixel_info->border_color);
  1724.   status=XParseColor(display,colormap,resource_info->border_color,
  1725.     &pixel_info->border_color);
  1726.   if (status == 0)
  1727.     Warning("Color is not known to X server",resource_info->border_color);
  1728.   pixel_info->border_color.pixel=
  1729.     XStandardPixel(map_info,pixel_info->border_color,16);
  1730.   pixel_info->border_color.flags=DoRed | DoGreen | DoBlue;
  1731.   /*
  1732.     Set matte color.
  1733.   */
  1734.   red=(int) (278*pixel_info->background_color.red) >> 8;
  1735.   pixel_info->matte_color.red=(red > 65535 ? 65535 : red);
  1736.   green=(int) (278*pixel_info->background_color.green) >> 8;
  1737.   pixel_info->matte_color.green=(green > 65535 ? 65535 : green);
  1738.   blue=(int) (278*pixel_info->background_color.blue) >> 8;
  1739.   pixel_info->matte_color.blue=(blue > 65535 ? 65535 : blue);
  1740.   pixel_info->matte_color.pixel=
  1741.     XStandardPixel(map_info,pixel_info->matte_color,16);
  1742.   pixel_info->highlight_color.flags=DoRed | DoGreen | DoBlue;
  1743.   if (resource_info->matte_color != (char *) NULL)
  1744.     {
  1745.       /*
  1746.         Matte color is specified as a X resource or command line argument.
  1747.       */
  1748.       status=XParseColor(display,colormap,resource_info->matte_color,
  1749.         &pixel_info->matte_color);
  1750.       if (status == 0)
  1751.         Warning("Color is not known to X server",resource_info->matte_color);
  1752.       pixel_info->matte_color.pixel=
  1753.         XStandardPixel(map_info,pixel_info->matte_color,16);
  1754.       pixel_info->matte_color.flags=DoRed | DoGreen | DoBlue;
  1755.     }
  1756.   /*
  1757.     Set highlight color.
  1758.   */
  1759.   red=(int) (309*pixel_info->matte_color.red) >> 8;
  1760.   pixel_info->highlight_color.red=(red > 65535 ? 65535 : red);
  1761.   green=(int) (309*pixel_info->matte_color.green) >> 8;
  1762.   pixel_info->highlight_color.green=(green > 65535 ? 65535 : green);
  1763.   blue=(int) (309*pixel_info->matte_color.blue) >> 8;
  1764.   pixel_info->highlight_color.blue=(blue > 65535 ? 65535 : blue);
  1765.   pixel_info->highlight_color.pixel=
  1766.     XStandardPixel(map_info,pixel_info->highlight_color,16);
  1767.   pixel_info->highlight_color.flags=DoRed | DoGreen | DoBlue;
  1768.   /*
  1769.     Set shadow color.
  1770.   */
  1771.   pixel_info->shadow_color.red=(int) (115*pixel_info->matte_color.red) >> 8;
  1772.   pixel_info->shadow_color.green=(int) (115*pixel_info->matte_color.green) >> 8;
  1773.   pixel_info->shadow_color.blue=(int) (115*pixel_info->matte_color.blue) >> 8;
  1774.   pixel_info->shadow_color.pixel=
  1775.     XStandardPixel(map_info,pixel_info->shadow_color,16);
  1776.   pixel_info->shadow_color.flags=DoRed | DoGreen | DoBlue;
  1777.   /*
  1778.     Set depth color.
  1779.   */
  1780.   pixel_info->depth_color.red=(int) (209*pixel_info->matte_color.red) >> 8;
  1781.   pixel_info->depth_color.green=(int) (209*pixel_info->matte_color.green) >> 8;
  1782.   pixel_info->depth_color.blue=(int) (209*pixel_info->matte_color.blue) >> 8;
  1783.   pixel_info->depth_color.pixel=
  1784.     XStandardPixel(map_info,pixel_info->depth_color,16);
  1785.   pixel_info->depth_color.flags=DoRed | DoGreen | DoBlue;
  1786.   /*
  1787.     Set trough color.
  1788.   */
  1789.   pixel_info->trough_color.red=(int) (134*pixel_info->matte_color.red) >> 8;
  1790.   pixel_info->trough_color.green=(int) (134*pixel_info->matte_color.green) >> 8;
  1791.   pixel_info->trough_color.blue=(int) (134*pixel_info->matte_color.blue) >> 8;
  1792.   pixel_info->trough_color.pixel=
  1793.     XStandardPixel(map_info,pixel_info->trough_color,16);
  1794.   pixel_info->trough_color.flags=DoRed | DoGreen | DoBlue;
  1795.   /*
  1796.     Set pen color.
  1797.   */
  1798.   for (i=0; i < MaxNumberPens; i++)
  1799.   {
  1800.     (void) XParseColor(display,colormap,PenColors[i],&pixel_info->pen_color[i]);
  1801.     status=XParseColor(display,colormap,resource_info->pen_color[i],
  1802.       &pixel_info->pen_color[i]);
  1803.     if (status == 0)
  1804.       Warning("Color is not known to X server",resource_info->pen_color[i]);
  1805.     pixel_info->pen_color[i].pixel=
  1806.       XStandardPixel(map_info,pixel_info->pen_color[i],16);
  1807.     pixel_info->pen_color[i].flags=DoRed | DoGreen | DoBlue;
  1808.   }
  1809.   pixel_info->annotate_color=pixel_info->foreground_color;
  1810.   if (image != (Image *) NULL)
  1811.     if (image->class == PseudoClass)
  1812.       {
  1813.         /*
  1814.           Initialize pixel array for images of type PseudoClass.
  1815.         */
  1816.         for (i=0; i < image->colors; i++)
  1817.           pixel_info->pixels[i]=XStandardPixel(map_info,image->colormap[i],8);
  1818.         for (i=0; i < MaxNumberPens; i++)
  1819.           pixel_info->pixels[image->colors+i]=pixel_info->pen_color[i].pixel;
  1820.         pixel_info->colors+=MaxNumberPens;
  1821.       }
  1822. }
  1823.  
  1824. /*
  1825. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1826. %                                                                             %
  1827. %                                                                             %
  1828. %                                                                             %
  1829. %   X G e t R e s o u r c e C l a s s                                         %
  1830. %                                                                             %
  1831. %                                                                             %
  1832. %                                                                             %
  1833. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1834. %
  1835. %  Function XGetResourceClass queries the X server for the specified resource
  1836. %  name or class.  If the resource name or class is not defined in the
  1837. %  database, the supplied default value is returned.
  1838. %
  1839. %  The format of the XGetResourceClass routine is:
  1840. %
  1841. %      value=XGetResourceClass(database,client_name,keyword,resource_default)
  1842. %
  1843. %  A description of each parameter follows:
  1844. %
  1845. %    o value: Function XGetResourceClass returns the resource value associated
  1846. %      with the name or class.  If none is found, the supplied default value is
  1847. %      returned.
  1848. %
  1849. %    o database: Specifies a resource database; returned from
  1850. %      XrmGetStringDatabase.
  1851. %
  1852. %    o client_name:  Specifies the application name used to retrieve resource
  1853. %      info from the X server database.
  1854. %
  1855. %    o keyword: Specifies the keyword of the value being retrieved.
  1856. %
  1857. %    o resource_default: Specifies the default value to return if the query
  1858. %      fails to find the specified keyword/class.
  1859. %
  1860. %
  1861. */
  1862. char *XGetResourceClass(database,client_name,keyword,resource_default)
  1863. XrmDatabase
  1864.   database;
  1865.  
  1866. char
  1867.   *client_name,
  1868.   *keyword,
  1869.   *resource_default;
  1870. {
  1871.   char
  1872.     *resource_type,
  1873.     resource_class[MaxTextLength],
  1874.     resource_name[MaxTextLength];
  1875.  
  1876.   int
  1877.     status;
  1878.  
  1879.   XrmValue
  1880.     resource_value;
  1881.  
  1882.   if (database == (XrmDatabase) NULL)
  1883.     return(resource_default);
  1884.   *resource_name='\0';
  1885.   *resource_class='\0';
  1886.   if (keyword != (char *) NULL)
  1887.     {
  1888.       unsigned char
  1889.         c,
  1890.         k;
  1891.  
  1892.       /*
  1893.         Initialize resource keyword and class.
  1894.       */
  1895.       (void) sprintf(resource_name,"%s.%s",client_name,keyword);
  1896.       c=(*client_name);
  1897.       if ((c >= XK_a) && (c <= XK_z))
  1898.         c-=(XK_a-XK_A);
  1899.       else
  1900.         if ((c >= XK_agrave) && (c <= XK_odiaeresis))
  1901.           c-=(XK_agrave-XK_Agrave);
  1902.         else
  1903.           if ((c >= XK_oslash) && (c <= XK_thorn))
  1904.             c-=(XK_oslash-XK_Ooblique);
  1905.       k=(*keyword);
  1906.       if ((k >= XK_a) && (k <= XK_z))
  1907.         k-=(XK_a-XK_A);
  1908.       else
  1909.         if ((k >= XK_agrave) && (k <= XK_odiaeresis))
  1910.           k-=(XK_agrave-XK_Agrave);
  1911.         else
  1912.           if ((k >= XK_oslash) && (k <= XK_thorn))
  1913.             k-=(XK_oslash-XK_Ooblique);
  1914.       (void) sprintf(resource_class,"%c%s.%c%s",c,client_name+1,k,keyword+1);
  1915.     }
  1916.   status=XrmGetResource(database,resource_name,resource_class,&resource_type,
  1917.     &resource_value);
  1918.   if (status == False)
  1919.     return(resource_default);
  1920.   return(resource_value.addr);
  1921. }
  1922.  
  1923. /*
  1924. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1925. %                                                                             %
  1926. %                                                                             %
  1927. %                                                                             %
  1928. %   X G e t R e s o u r c e I n f o                                           %
  1929. %                                                                             %
  1930. %                                                                             %
  1931. %                                                                             %
  1932. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1933. %
  1934. %  Function XGetResourceInfo initializes the ResourceInfo structure.
  1935. %
  1936. %  The format of the XGetResourceInfo routine is:
  1937. %
  1938. %      XGetResourceInfo(resource_database,client_name,resource_info)
  1939. %
  1940. %  A description of each parameter follows:
  1941. %
  1942. %    o resource_database: Specifies a resource database; returned from
  1943. %      XrmGetStringDatabase.
  1944. %
  1945. %    o client_name:  Specifies the application name used to retrieve
  1946. %      resource info from the X server database.
  1947. %
  1948. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  1949. %
  1950. %
  1951. */
  1952. void XGetResourceInfo(resource_database,client_name,resource_info)
  1953. XrmDatabase
  1954.   resource_database;
  1955.  
  1956. char
  1957.   *client_name;
  1958.  
  1959. XResourceInfo
  1960.   *resource_info;
  1961. {
  1962.   char
  1963.     *resource_value;
  1964.  
  1965.   register char
  1966.     *p;
  1967.  
  1968.   if (client_name != (char *) NULL)
  1969.     {
  1970.       /*
  1971.         Get basename of client.
  1972.       */
  1973.       p=client_name+(strlen(client_name)-1);
  1974.       while ((p > client_name) && (*p != '/'))
  1975.         p--;
  1976.       if (*p == '/')
  1977.         client_name=p+1;
  1978.     }
  1979.   /*
  1980.     Initialize resource info fields.
  1981.   */
  1982.   resource_info->resource_database=resource_database;
  1983.   resource_value=
  1984.     XGetResourceClass(resource_database,client_name,"backdrop","False");
  1985.   resource_info->backdrop=IsTrue(resource_value);
  1986.   resource_info->background_color=XGetResourceInstance(resource_database,
  1987.     client_name,"background",BackgroundColor);
  1988.   resource_info->border_color=XGetResourceInstance(resource_database,
  1989.     client_name,"borderColor",BorderColor);
  1990.   resource_value=
  1991.     XGetResourceClass(resource_database,client_name,"borderWidth","2");
  1992.   resource_info->border_width=atoi(resource_value);
  1993.   resource_value=
  1994.     XGetResourceClass(resource_database,client_name,"colormap","shared");
  1995.   resource_info->colormap=UndefinedColormap;
  1996.   if (Latin1Compare("private",resource_value) == 0)
  1997.     resource_info->colormap=PrivateColormap;
  1998.   if (Latin1Compare("shared",resource_value) == 0)
  1999.     resource_info->colormap=SharedColormap;
  2000.   if (resource_info->colormap == UndefinedColormap)
  2001.     Warning("Unrecognized colormap type",resource_value);
  2002.   resource_value=XGetResourceClass(resource_database,client_name,"colors","0");
  2003.   resource_info->number_colors=atoi(resource_value);
  2004.   resource_value=
  2005.     XGetResourceClass(resource_database,client_name,"colorspace","rgb");
  2006.   resource_info->colorspace=UndefinedColorspace;
  2007.   if (Latin1Compare("gray",resource_value) == 0)
  2008.     resource_info->colorspace=GRAYColorspace;
  2009.   if (Latin1Compare("rgb",resource_value) == 0)
  2010.     resource_info->colorspace=RGBColorspace;
  2011.   if (Latin1Compare("ohta",resource_value) == 0)
  2012.     resource_info->colorspace=OHTAColorspace;
  2013.   if (Latin1Compare("xyz",resource_value) == 0)
  2014.     resource_info->colorspace=XYZColorspace;
  2015.   if (Latin1Compare("yiq",resource_value) == 0)
  2016.     resource_info->colorspace=YIQColorspace;
  2017.   if (Latin1Compare("yuv",resource_value) == 0)
  2018.     resource_info->colorspace=YUVColorspace;
  2019.   if (resource_info->colorspace == UndefinedColorspace)
  2020.     Warning("Unrecognized colorspace type",resource_value);
  2021.   resource_info->editor_command=XGetResourceClass(resource_database,client_name,
  2022.     "editorCommand",EditorCommand);
  2023.   resource_value=
  2024.     XGetResourceClass(resource_database,client_name,"debug","False");
  2025.   resource_info->debug=IsTrue(resource_value);
  2026.   resource_value=XGetResourceClass(resource_database,client_name,"delay","0");
  2027.   resource_info->delay=atoi(resource_value);
  2028.   resource_value=
  2029.     XGetResourceClass(resource_database,client_name,"dither","False");
  2030.   resource_info->dither=IsTrue(resource_value);
  2031.   resource_info->font=
  2032.     XGetResourceClass(resource_database,client_name,"FontList",(char *) NULL);
  2033.   resource_info->font_name[0]=
  2034.     XGetResourceClass(resource_database,client_name,"font1","fixed");
  2035.   resource_info->font_name[1]=
  2036.     XGetResourceClass(resource_database,client_name,"font2","variable");
  2037.   resource_info->font_name[2]=
  2038.     XGetResourceClass(resource_database,client_name,"font3","5x8");
  2039.   resource_info->font_name[3]=
  2040.     XGetResourceClass(resource_database,client_name,"font4","6x10");
  2041.   resource_info->font_name[4]=
  2042.     XGetResourceClass(resource_database,client_name,"font5","7x13bold");
  2043.   resource_info->font_name[5]=
  2044.     XGetResourceClass(resource_database,client_name,"font6","8x13bold");
  2045.   resource_info->font_name[6]=
  2046.     XGetResourceClass(resource_database,client_name,"font7","9x15bold");
  2047.   resource_info->font_name[7]=
  2048.     XGetResourceClass(resource_database,client_name,"font8","10x20");
  2049.   resource_info->font_name[8]=
  2050.     XGetResourceClass(resource_database,client_name,"font9","12x24");
  2051.   resource_info->font_name[9]=
  2052.     XGetResourceClass(resource_database,client_name,"font0","fixed");
  2053.   resource_info->foreground_color=XGetResourceInstance(resource_database,
  2054.     client_name,"foreground",ForegroundColor);
  2055.   resource_info->icon_geometry=XGetResourceClass(resource_database,client_name,
  2056.     "iconGeometry",(char *) NULL);
  2057.   resource_value=
  2058.     XGetResourceClass(resource_database,client_name,"gravity","North");
  2059.   resource_info->gravity=(-1);
  2060.   if (Latin1Compare("Forget",resource_value) == 0)
  2061.     resource_info->gravity=ForgetGravity;
  2062.   if (Latin1Compare("NorthWest",resource_value) == 0)
  2063.     resource_info->gravity=NorthWestGravity;
  2064.   if (Latin1Compare("North",resource_value) == 0)
  2065.     resource_info->gravity=NorthGravity;
  2066.   if (Latin1Compare("NorthEast",resource_value) == 0)
  2067.     resource_info->gravity=NorthEastGravity;
  2068.   if (Latin1Compare("West",resource_value) == 0)
  2069.     resource_info->gravity=WestGravity;
  2070.   if (Latin1Compare("Center",resource_value) == 0)
  2071.     resource_info->gravity=CenterGravity;
  2072.   if (Latin1Compare("East",resource_value) == 0)
  2073.     resource_info->gravity=EastGravity;
  2074.   if (Latin1Compare("SouthWest",resource_value) == 0)
  2075.     resource_info->gravity=SouthWestGravity;
  2076.   if (Latin1Compare("South",resource_value) == 0)
  2077.     resource_info->gravity=SouthGravity;
  2078.   if (Latin1Compare("SouthEast",resource_value) == 0)
  2079.     resource_info->gravity=SouthEastGravity;
  2080.   if (Latin1Compare("Static",resource_value) == 0)
  2081.     resource_info->gravity=StaticGravity;
  2082.   if (resource_info->gravity == (-1))
  2083.     {
  2084.       Warning("Unrecognized gravity type",resource_value);
  2085.       resource_info->gravity=CenterGravity;
  2086.     }
  2087.   resource_value=
  2088.     XGetResourceClass(resource_database,client_name,"iconic","False");
  2089.   resource_info->iconic=IsTrue(resource_value);
  2090.   resource_info->image_geometry=XGetResourceClass(resource_database,
  2091.     client_name,"imageGeometry",(char *) NULL);
  2092.   resource_value=XGetResourceClass(resource_database,client_name,"magnify","3");
  2093.   resource_info->magnify=atoi(resource_value);
  2094.   resource_info->map_type=
  2095.     XGetResourceClass(resource_database,client_name,"map",(char *) NULL);
  2096.   resource_info->matte_color=
  2097.     XGetResourceInstance(resource_database,client_name,"matte",(char *) NULL);
  2098.   resource_value=
  2099.     XGetResourceClass(resource_database,client_name,"monochrome","False");
  2100.   resource_info->monochrome=IsTrue(resource_value);
  2101.   resource_info->name=
  2102.     XGetResourceClass(resource_database,client_name,"name",(char *) NULL);
  2103.   resource_info->pen_color[0]=
  2104.     XGetResourceClass(resource_database,client_name,"pen1","black");
  2105.   resource_info->pen_color[1]=
  2106.     XGetResourceClass(resource_database,client_name,"pen2","blue");
  2107.   resource_info->pen_color[2]=
  2108.     XGetResourceClass(resource_database,client_name,"pen3","cyan");
  2109.   resource_info->pen_color[3]=
  2110.     XGetResourceClass(resource_database,client_name,"pen4","green");
  2111.   resource_info->pen_color[4]=
  2112.     XGetResourceClass(resource_database,client_name,"pen5","gray");
  2113.   resource_info->pen_color[5]=
  2114.     XGetResourceClass(resource_database,client_name,"pen6","red");
  2115.   resource_info->pen_color[6]=
  2116.     XGetResourceClass(resource_database,client_name,"pen7","magenta");
  2117.   resource_info->pen_color[7]=
  2118.     XGetResourceClass(resource_database,client_name,"pen8","yellow");
  2119.   resource_info->pen_color[8]=
  2120.     XGetResourceClass(resource_database,client_name,"pen9","white");
  2121.   resource_info->pen_color[9]=
  2122.     XGetResourceClass(resource_database,client_name,"pen0","gray");
  2123.   resource_info->print_command=XGetResourceClass(resource_database,client_name,
  2124.     "printCommand",PrintCommand);
  2125.   resource_info->server_name=
  2126.     XGetResourceClass(resource_database,client_name,"serverName",(char *) NULL);
  2127.   resource_info->title=
  2128.     XGetResourceClass(resource_database,client_name,"title",(char *) NULL);
  2129.   resource_value=
  2130.     XGetResourceClass(resource_database,client_name,"treeDepth","0");
  2131.   resource_info->tree_depth=atoi(resource_value);
  2132.   resource_value=
  2133.     XGetResourceClass(resource_database,client_name,"update","False");
  2134.   resource_info->update=IsTrue(resource_value);
  2135.   resource_value=
  2136.     XGetResourceClass(resource_database,client_name,"usePixmap","False");
  2137.   resource_info->use_pixmap=IsTrue(resource_value);
  2138.   resource_info->visual_type=
  2139.     XGetResourceClass(resource_database,client_name,"visual",(char *) NULL);
  2140.   resource_info->window_id=
  2141.     XGetResourceClass(resource_database,client_name,"window",(char *) NULL);
  2142.   resource_info->write_filename=XGetResourceClass(resource_database,
  2143.     client_name,"writeFilename",(char *) NULL);
  2144.   /*
  2145.     Handle side-effects.
  2146.   */
  2147.   if (resource_info->monochrome)
  2148.     {
  2149.       resource_info->number_colors=2;
  2150.       resource_info->tree_depth=8;
  2151.       resource_info->dither=True;
  2152.       resource_info->colorspace=GRAYColorspace;
  2153.     }
  2154.   if (resource_info->colorspace == GRAYColorspace)
  2155.     {
  2156.       resource_info->number_colors=256;
  2157.       resource_info->tree_depth=8;
  2158.     }
  2159. }
  2160.  
  2161. /*
  2162. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2163. %                                                                             %
  2164. %                                                                             %
  2165. %                                                                             %
  2166. %   X G e t R e s o u r c e I n s t a n c e                                   %
  2167. %                                                                             %
  2168. %                                                                             %
  2169. %                                                                             %
  2170. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2171. %
  2172. %  Function XGetResourceInstance queries the X server for the specified
  2173. %  resource name.  If the resource name is not defined in the database, the
  2174. %  supplied default value is returned.
  2175. %
  2176. %  The format of the XGetResourceInstance routine is:
  2177. %
  2178. %      value=XGetResourceInstance(database,client_name,keyword,resource_default)
  2179. %
  2180. %  A description of each parameter follows:
  2181. %
  2182. %    o value: Function XGetResourceInstance returns the resource value
  2183. %      associated with the name or class.  If none is found, the supplied
  2184. %      default value is returned.
  2185. %
  2186. %    o database: Specifies a resource database; returned from
  2187. %      XrmGetStringDatabase.
  2188. %
  2189. %    o client_name:  Specifies the application name used to retrieve
  2190. %      resource info from the X server database.
  2191. %
  2192. %    o keyword: Specifies the keyword of the value being retrieved.
  2193. %
  2194. %    o resource_default: Specifies the default value to return if the query
  2195. %      fails to find the specified keyword/class.
  2196. %
  2197. %
  2198. */
  2199. static char *XGetResourceInstance(database,client_name,keyword,resource_default)
  2200. XrmDatabase
  2201.   database;
  2202.  
  2203. char
  2204.   *client_name,
  2205.   *keyword,
  2206.   *resource_default;
  2207. {
  2208.   char
  2209.     *resource_type,
  2210.     resource_name[MaxTextLength];
  2211.  
  2212.   int
  2213.     status;
  2214.  
  2215.   XrmValue
  2216.     resource_value;
  2217.  
  2218.   if (database == (XrmDatabase) NULL)
  2219.     return(resource_default);
  2220.   *resource_name='\0';
  2221.   if (keyword != (char *) NULL)
  2222.     (void) sprintf(resource_name,"%s.%s",client_name,keyword);
  2223.   status=XrmGetResource(database,resource_name,(char *) NULL,&resource_type,
  2224.     &resource_value);
  2225.   if (status == False)
  2226.     return(resource_default);
  2227.   return(resource_value.addr);
  2228. }
  2229.  
  2230. /*
  2231. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2232. %                                                                             %
  2233. %                                                                             %
  2234. %                                                                             %
  2235. %   X G e t W i n d o w C o l o r                                             %
  2236. %                                                                             %
  2237. %                                                                             %
  2238. %                                                                             %
  2239. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2240. %
  2241. %  Function XGetWindowColor returns the color of a pixel interactively choosen
  2242. %  from the X server.
  2243. %
  2244. %  The format of the XGetWindowImage routine is:
  2245. %
  2246. %      status=XGetWindowImage(display,color)
  2247. %
  2248. %  A description of each parameter follows:
  2249. %
  2250. %    o status: Function XGetWindowColor returns True if the color is obtained
  2251. %      from the X server.  False is returned if any errors occurs.
  2252. %
  2253. %    o display: Specifies a connection to an X server;  returned from
  2254. %      XOpenDisplay.
  2255. %
  2256. %    o color: The color of the pixel choosen is returned in this XColor
  2257. %      structure.
  2258. %
  2259. %
  2260. */
  2261. unsigned int XGetWindowColor(display,color)
  2262. Display
  2263.   *display;
  2264.  
  2265. XColor
  2266.   *color;
  2267. {
  2268.   int
  2269.     x,
  2270.     y;
  2271.  
  2272.   RectangleInfo
  2273.     clip_info;
  2274.  
  2275.   unsigned int
  2276.     status;
  2277.  
  2278.   Window
  2279.     child,
  2280.     client_window,
  2281.     root_window,
  2282.     target_window;
  2283.  
  2284.   XImage
  2285.     *ximage;
  2286.  
  2287.   XWindowAttributes
  2288.     window_attributes;
  2289.  
  2290.   /*
  2291.     Choose a pixel from the X server.
  2292.   */
  2293.   target_window=XSelectWindow(display,&clip_info);
  2294.   root_window=XRootWindow(display,XDefaultScreen(display));
  2295.   client_window=target_window;
  2296.   if (target_window != root_window)
  2297.     {
  2298.       unsigned int
  2299.         d;
  2300.  
  2301.       /*
  2302.         Get client window.
  2303.       */
  2304.       status=XGetGeometry(display,target_window,&root_window,&x,&x,&d,&d,&d,&d);
  2305.       if (status != 0)
  2306.         {
  2307.           client_window=XClientWindow(display,target_window);
  2308.           target_window=client_window;
  2309.         }
  2310.     }
  2311.   /*
  2312.     Verify window is viewable.
  2313.   */
  2314.   status=XGetWindowAttributes(display,target_window,&window_attributes);
  2315.   if ((status == False) || (window_attributes.map_state != IsViewable))
  2316.     return(False);
  2317.   /*
  2318.     Get window X image.
  2319.   */
  2320.   XTranslateCoordinates(display,root_window,target_window,clip_info.x,
  2321.     clip_info.y,&x,&y,&child);
  2322.   ximage=XGetImage(display,target_window,x,y,1,1,AllPlanes,ZPixmap);
  2323.   if (ximage == (XImage *) NULL)
  2324.     return(False);
  2325.   color->pixel=XGetPixel(ximage,0,0);
  2326.   XDestroyImage(ximage);
  2327.   /*
  2328.     Query X server for pixel color.
  2329.   */
  2330.   XQueryColor(display,window_attributes.colormap,color);
  2331.   return(True);
  2332. }
  2333.  
  2334. /*
  2335. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2336. %                                                                             %
  2337. %                                                                             %
  2338. %                                                                             %
  2339. %   X G e t W i n d o w I m a g e                                             %
  2340. %                                                                             %
  2341. %                                                                             %
  2342. %                                                                             %
  2343. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2344. %
  2345. %  Function XGetWindowImage reads an image from the target X window and returns
  2346. %  it.  XGetWindowImage optionally descends the window hierarchy and overlays
  2347. %  the target image with each subwindow image.
  2348. %
  2349. %  The format of the XGetWindowImage routine is:
  2350. %
  2351. %      image=XGetWindowImage(display,window,borders,level)
  2352. %
  2353. %  A description of each parameter follows:
  2354. %
  2355. %    o image: Function XGetWindowImage returns a MIFF image if it can be
  2356. %      successfully read from the X window.  A null image is returned if
  2357. %      any errors occurs.
  2358. %
  2359. %    o display: Specifies a connection to an X server;  returned from
  2360. %      XOpenDisplay.
  2361. %
  2362. %    o window: Specifies the window to obtain the image from.
  2363. %
  2364. %    o borders: Specifies whether borders pixels are to be saved with
  2365. %      the image.
  2366. %
  2367. %    o level: Specifies an unsigned integer representing the level of
  2368. %      decent in the window hierarchy.  This value must be zero or one on
  2369. %      the initial call to XGetWindowImage.  A value of zero returns after
  2370. %      one call.  A value of one causes the function to descend the window
  2371. %      hierarchy and overlays the target image with each subwindow image.
  2372. %
  2373. %
  2374. */
  2375. Image *XGetWindowImage(display,window,borders,level)
  2376. Display
  2377.   *display;
  2378.  
  2379. Window
  2380.   window;
  2381.  
  2382. unsigned int
  2383.   borders,
  2384.   level;
  2385. {
  2386.   typedef struct _ColormapList
  2387.   {
  2388.     Colormap
  2389.       colormap;
  2390.  
  2391.     XColor
  2392.       *colors;
  2393.  
  2394.     struct _ColormapList
  2395.       *next;
  2396.   } ColormapList;
  2397.  
  2398.   GC
  2399.     annotate_context;
  2400.  
  2401.   Image
  2402.     *image;
  2403.  
  2404.   int
  2405.     display_height,
  2406.     display_width,
  2407.     number_colors,
  2408.     status,
  2409.     x_offset,
  2410.     y_offset;
  2411.  
  2412.   RectangleInfo
  2413.     clip_info;
  2414.  
  2415.   register int
  2416.     i,
  2417.     x,
  2418.     y;
  2419.  
  2420.   register RunlengthPacket
  2421.     *p;
  2422.  
  2423.   register unsigned long
  2424.     pixel;
  2425.  
  2426.   static ColormapList
  2427.     *colormap_list = (ColormapList *) NULL;
  2428.  
  2429.   Window
  2430.     child,
  2431.     root_window;
  2432.  
  2433.   XColor
  2434.     *colors;
  2435.  
  2436.   XGCValues
  2437.     context_values;
  2438.  
  2439.   XImage
  2440.     *ximage;
  2441.  
  2442.   XWindowAttributes
  2443.     window_attributes;
  2444.  
  2445.   /*
  2446.     Verify window is viewable.
  2447.   */
  2448.   status=XGetWindowAttributes(display,window,&window_attributes);
  2449.   if ((status == False) || (window_attributes.map_state != IsViewable))
  2450.     return((Image *) NULL);
  2451.   /*
  2452.     Clipping rectangle is relative to root window.
  2453.   */
  2454.   root_window=XRootWindow(display,XDefaultScreen(display));
  2455.   XTranslateCoordinates(display,window,root_window,0,0,&x_offset,&y_offset,
  2456.     &child);
  2457.   clip_info.x=x_offset;
  2458.   clip_info.y=y_offset;
  2459.   clip_info.width=window_attributes.width;
  2460.   clip_info.height=window_attributes.height;
  2461.   if (borders)
  2462.     {
  2463.       /*
  2464.         Include border in image.
  2465.       */
  2466.       clip_info.x-=window_attributes.border_width;
  2467.       clip_info.y-=window_attributes.border_width;
  2468.       clip_info.width+=window_attributes.border_width << 1;
  2469.       clip_info.height+=window_attributes.border_width << 1;
  2470.     }
  2471.   /*
  2472.     Clip to root window.
  2473.   */
  2474.   if (clip_info.x < 0)
  2475.     {
  2476.       if ((clip_info.x+(int) clip_info.width) < 0)
  2477.         return((Image *) NULL);
  2478.       clip_info.width+=clip_info.x;
  2479.       clip_info.x=0;
  2480.     }
  2481.   if (clip_info.y < 0)
  2482.     {
  2483.       if ((clip_info.y+(int) clip_info.height) < 0)
  2484.         return((Image *) NULL);
  2485.       clip_info.height+=clip_info.y;
  2486.       clip_info.y=0;
  2487.     }
  2488.   display_width=XDisplayWidth(display,XDefaultScreen(display));
  2489.   if ((clip_info.x+(int) clip_info.width) > display_width)
  2490.     {
  2491.       if (clip_info.x >= display_width)
  2492.         return((Image *) NULL);
  2493.       clip_info.width=display_width-clip_info.x;
  2494.     }
  2495.   display_height=XDisplayHeight(display,XDefaultScreen(display));
  2496.   if ((clip_info.y+(int) clip_info.height) > display_height)
  2497.     {
  2498.       if (clip_info.y >= display_height)
  2499.         return((Image *) NULL);
  2500.       clip_info.height=display_height-clip_info.y;
  2501.     }
  2502.   clip_info.x-=x_offset;
  2503.   clip_info.y-=y_offset;
  2504.   /*
  2505.     Alert user we are about to get an X region by flashing a border.
  2506.   */
  2507.   context_values.background=XBlackPixel(display,XDefaultScreen(display));
  2508.   context_values.foreground=XWhitePixel(display,XDefaultScreen(display));
  2509.   context_values.function=GXinvert;
  2510.   context_values.plane_mask=
  2511.     context_values.background ^ context_values.foreground;
  2512.   context_values.subwindow_mode=IncludeInferiors;
  2513.   annotate_context=XCreateGC(display,window,GCBackground | GCForeground |
  2514.     GCFunction | GCPlaneMask | GCSubwindowMode,&context_values);
  2515.   if (annotate_context != (GC) NULL)
  2516.     {
  2517.       XHighlightRegion(display,window,annotate_context,&clip_info);
  2518.       XDelay(display,SuspendTime << 2);
  2519.       XHighlightRegion(display,window,annotate_context,&clip_info);
  2520.     }
  2521.   /*
  2522.     Get window X image.
  2523.   */
  2524.   ximage=XGetImage(display,window,clip_info.x,clip_info.y,clip_info.width,
  2525.     clip_info.height,AllPlanes,ZPixmap);
  2526.   if (ximage == (XImage *) NULL)
  2527.     return((Image *) NULL);
  2528.   number_colors=0;
  2529.   colors=(XColor *) NULL;
  2530.   if (window_attributes.colormap != (Colormap) NULL)
  2531.     {
  2532.       ColormapList
  2533.         *p;
  2534.  
  2535.       /*
  2536.         Search colormap list for window colormap.
  2537.       */
  2538.       number_colors=window_attributes.visual->map_entries;
  2539.       for (p=colormap_list; p != (ColormapList *) NULL; p=p->next)
  2540.         if (p->colormap == window_attributes.colormap)
  2541.           break;
  2542.       if (p == (ColormapList *) NULL)
  2543.         {
  2544.           /*
  2545.             Get the window colormap.
  2546.           */
  2547.           colors=(XColor *) malloc(number_colors*sizeof(XColor));
  2548.           if (colors == (XColor *) NULL)
  2549.             {
  2550.               XDestroyImage(ximage);
  2551.               return((Image *) NULL);
  2552.             }
  2553.           if ((window_attributes.visual->class != DirectColor) &&
  2554.               (window_attributes.visual->class != TrueColor))
  2555.             for (i=0; i < number_colors; i++)
  2556.             {
  2557.               colors[i].pixel=i;
  2558.               colors[i].pad=0;
  2559.             }
  2560.           else
  2561.             {
  2562.               unsigned long
  2563.                 blue,
  2564.                 blue_bit,
  2565.                 green,
  2566.                 green_bit,
  2567.                 red,
  2568.                 red_bit;
  2569.  
  2570.               /*
  2571.                 DirectColor or TrueColor visual.
  2572.               */
  2573.               red=0;
  2574.               green=0;
  2575.               blue=0;
  2576.               red_bit=window_attributes.visual->red_mask &
  2577.                 (~(window_attributes.visual->red_mask)+1);
  2578.               green_bit=window_attributes.visual->green_mask &
  2579.                 (~(window_attributes.visual->green_mask)+1);
  2580.               blue_bit=window_attributes.visual->blue_mask &
  2581.                 (~(window_attributes.visual->blue_mask)+1);
  2582.               for (i=0; i < number_colors; i++)
  2583.               {
  2584.                 colors[i].pixel=red | green | blue;
  2585.                 colors[i].pad=0;
  2586.                 red+=red_bit;
  2587.                 if (red > window_attributes.visual->red_mask)
  2588.                   red=0;
  2589.                 green+=green_bit;
  2590.                 if (green > window_attributes.visual->green_mask)
  2591.                   green=0;
  2592.                 blue+=blue_bit;
  2593.                 if (blue > window_attributes.visual->blue_mask)
  2594.                   blue=0;
  2595.               }
  2596.             }
  2597.           XQueryColors(display,window_attributes.colormap,colors,
  2598.            (int) number_colors);
  2599.           /*
  2600.             Append colormap to colormap list.
  2601.           */
  2602.           p=(ColormapList *) malloc(sizeof(ColormapList));
  2603.           p->colormap=window_attributes.colormap;
  2604.           p->colors=colors;
  2605.           p->next=colormap_list;
  2606.           colormap_list=p;
  2607.         }
  2608.       colors=p->colors;
  2609.     }
  2610.   /*
  2611.     Allocate image structure.
  2612.   */
  2613.   image=AllocateImage((ImageInfo *) NULL);
  2614.   if (image == (Image *) NULL)
  2615.     {
  2616.       XDestroyImage(ximage);
  2617.       return((Image *) NULL);
  2618.     }
  2619.   /*
  2620.     Convert X image to MIFF format.
  2621.   */
  2622.   if ((window_attributes.visual->class != TrueColor) &&
  2623.       (window_attributes.visual->class != DirectColor))
  2624.     image->class=PseudoClass;
  2625.   image->columns=ximage->width;
  2626.   image->rows=ximage->height;
  2627.   image->packets=image->columns*image->rows;
  2628.   image->pixels=(RunlengthPacket *)
  2629.     malloc((unsigned int) image->packets*sizeof(RunlengthPacket));
  2630.   if (image->pixels == (RunlengthPacket *) NULL)
  2631.     {
  2632.       XDestroyImage(ximage);
  2633.       DestroyImage(image);
  2634.       return((Image *) NULL);
  2635.     }
  2636.   p=image->pixels;
  2637.   switch (image->class)
  2638.   {
  2639.     case DirectClass:
  2640.     {
  2641.       register unsigned long
  2642.         color,
  2643.         index;
  2644.  
  2645.       unsigned long
  2646.         blue_mask,
  2647.         blue_shift,
  2648.         green_mask,
  2649.         green_shift,
  2650.         red_mask,
  2651.         red_shift;
  2652.  
  2653.       /*
  2654.         Determine shift and mask for red, green, and blue.
  2655.       */
  2656.       red_mask=window_attributes.visual->red_mask;
  2657.       red_shift=0;
  2658.       while ((red_mask & 0x01) == 0)
  2659.       {
  2660.         red_mask>>=1;
  2661.         red_shift++;
  2662.       }
  2663.       green_mask=window_attributes.visual->green_mask;
  2664.       green_shift=0;
  2665.       while ((green_mask & 0x01) == 0)
  2666.       {
  2667.         green_mask>>=1;
  2668.         green_shift++;
  2669.       }
  2670.       blue_mask=window_attributes.visual->blue_mask;
  2671.       blue_shift=0;
  2672.       while ((blue_mask & 0x01) == 0)
  2673.       {
  2674.         blue_mask>>=1;
  2675.         blue_shift++;
  2676.       }
  2677.       /*
  2678.         Convert X image to DirectClass packets.
  2679.       */
  2680.       if ((number_colors > 0) &&
  2681.           (window_attributes.visual->class == DirectColor))
  2682.         for (y=0; y < image->rows; y++)
  2683.         {
  2684.           for (x=0; x < image->columns; x++)
  2685.           {
  2686.             pixel=XGetPixel(ximage,x,y);
  2687.             index=(pixel >> red_shift) & red_mask;
  2688.             p->red=(unsigned char) (colors[index].red >> 8);
  2689.             index=(pixel >> green_shift) & green_mask;
  2690.             p->green=(unsigned char) (colors[index].green >> 8);
  2691.             index=(pixel >> blue_shift) & blue_mask;
  2692.             p->blue=(unsigned char) (colors[index].blue >> 8);
  2693.             p->index=0;
  2694.             p->length=0;
  2695.             p++;
  2696.           }
  2697.         }
  2698.       else
  2699.         for (y=0; y < image->rows; y++)
  2700.           for (x=0; x < image->columns; x++)
  2701.           {
  2702.             pixel=XGetPixel(ximage,x,y);
  2703.             color=(pixel >> red_shift) & red_mask;
  2704.             p->red=(unsigned char)
  2705.               ((((unsigned long) color*65535)/red_mask) >> 8);
  2706.             color=(pixel >> green_shift) & green_mask;
  2707.             p->green=(unsigned char)
  2708.               ((((unsigned long) color*65535)/green_mask) >> 8);
  2709.             color=(pixel >> blue_shift) & blue_mask;
  2710.             p->blue=(unsigned char)
  2711.               ((((unsigned long) color*65535)/blue_mask) >> 8);
  2712.             p->index=0;
  2713.             p->length=0;
  2714.             p++;
  2715.           }
  2716.       break;
  2717.     }
  2718.     case PseudoClass:
  2719.     {
  2720.       /*
  2721.         Create colormap.
  2722.       */
  2723.       image->colors=number_colors;
  2724.       image->colormap=(ColorPacket *) malloc(image->colors*sizeof(ColorPacket));
  2725.       if (image->colormap == (ColorPacket *) NULL)
  2726.         {
  2727.           XDestroyImage(ximage);
  2728.           DestroyImage(image);
  2729.           return((Image *) NULL);
  2730.         }
  2731.       for (i=0; i < image->colors; i++)
  2732.       {
  2733.         image->colormap[colors[i].pixel].red=colors[i].red >> 8;
  2734.         image->colormap[colors[i].pixel].green=colors[i].green >> 8;
  2735.         image->colormap[colors[i].pixel].blue=colors[i].blue >> 8;
  2736.       }
  2737.       /*
  2738.         Convert X image to PseudoClass packets.
  2739.       */
  2740.       for (y=0; y < image->rows; y++)
  2741.         for (x=0; x < image->columns; x++)
  2742.         {
  2743.           pixel=XGetPixel(ximage,x,y);
  2744.           p->index=(unsigned short) pixel;
  2745.           p->length=0;
  2746.           p++;
  2747.         }
  2748.       SyncImage(image);
  2749.       break;
  2750.     }
  2751.   }
  2752.   XDestroyImage(ximage);
  2753.   if (annotate_context != (GC) NULL)
  2754.     {
  2755.       /*
  2756.         Alert user we got the X region by flashing a border.
  2757.       */
  2758.       XHighlightRegion(display,window,annotate_context,&clip_info);
  2759.       XFlush(display);
  2760.       XHighlightRegion(display,window,annotate_context,&clip_info);
  2761.       XFreeGC(display,annotate_context);
  2762.     }
  2763.   if (level != 0)
  2764.     {
  2765.       unsigned int
  2766.         number_children;
  2767.  
  2768.       Window
  2769.         *children,
  2770.         parent;
  2771.  
  2772.       /*
  2773.         Descend the window hierarchy and overlay with each subwindow image.
  2774.       */
  2775.       status=XQueryTree(display,window,&root_window,&parent,&children,
  2776.         &number_children);
  2777.       if ((status == True) && (number_children != 0))
  2778.         {
  2779.           Image
  2780.             *child_image;
  2781.  
  2782.           /*
  2783.             Composite any children in back-to-front order.
  2784.           */
  2785.           for (i=0; i < number_children; i++)
  2786.           {
  2787.             child_image=XGetWindowImage(display,children[i],False,level+1);
  2788.             if (child_image != (Image *) NULL)
  2789.               {
  2790.                 /*
  2791.                   Composite child window image.
  2792.                 */
  2793.                 XTranslateCoordinates(display,children[i],window,0,0,&x_offset,
  2794.                   &y_offset,&child);
  2795.                 x_offset-=clip_info.x;
  2796.                 if (x_offset < 0)
  2797.                   x_offset=0;
  2798.                 y_offset-=clip_info.y;
  2799.                 if (y_offset < 0)
  2800.                   y_offset=0;
  2801.                 CompositeImage(image,ReplaceCompositeOp,child_image,x_offset,
  2802.                   y_offset);
  2803.                 DestroyImage(child_image);
  2804.               }
  2805.           }
  2806.           XFree((void *) children);
  2807.         }
  2808.     }
  2809.   if (level <= 1)
  2810.     {
  2811.       ColormapList
  2812.         *next;
  2813.  
  2814.       /*
  2815.         Free resources.
  2816.       */
  2817.       while (colormap_list != (ColormapList *) NULL)
  2818.       {
  2819.         next=colormap_list->next;
  2820.         (void) free((char *) colormap_list->colors);
  2821.         (void) free((char *) colormap_list);
  2822.         colormap_list=next;
  2823.       }
  2824.       if (image->class == PseudoClass)
  2825.         CompressColormap(image);
  2826.     }
  2827.   return(image);
  2828. }
  2829.  
  2830. /*
  2831. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2832. %                                                                             %
  2833. %                                                                             %
  2834. %                                                                             %
  2835. %   X G e t W i n d o w I n f o                                               %
  2836. %                                                                             %
  2837. %                                                                             %
  2838. %                                                                             %
  2839. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2840. %
  2841. %  Function XGetWindowInfo initializes the XWindowInfo structure.
  2842. %
  2843. %  The format of the XGetWindowInfo routine is:
  2844. %
  2845. %      XGetWindowInfo(display,visual_info,map_info,pixel_info,font_info,
  2846. %        resource_info,window)
  2847. %
  2848. %  A description of each parameter follows:
  2849. %
  2850. %    o display: Specifies a connection to an X server; returned from
  2851. %      XOpenDisplay.
  2852. %
  2853. %    o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
  2854. %      returned from XGetVisualInfo.
  2855. %
  2856. %    o map_info: If map_type is specified, this structure is initialized
  2857. %      with info from the Standard Colormap.
  2858. %
  2859. %    o pixel_info: Specifies a pointer to a XPixelInfo structure.
  2860. %
  2861. %    o font_info: Specifies a pointer to a XFontStruct structure.
  2862. %
  2863. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  2864. %
  2865. %
  2866. */
  2867. void XGetWindowInfo(display,visual_info,map_info,pixel_info,font_info,
  2868.   resource_info,window)
  2869. Display
  2870.   *display;
  2871.  
  2872. XVisualInfo
  2873.   *visual_info;
  2874.  
  2875. XStandardColormap
  2876.  *map_info;
  2877.  
  2878. XPixelInfo
  2879.   *pixel_info;
  2880.  
  2881. XFontStruct
  2882.   *font_info;
  2883.  
  2884. XResourceInfo
  2885.   *resource_info;
  2886.  
  2887. XWindowInfo
  2888.   *window;
  2889. {
  2890.   /*
  2891.     Initialize window info.
  2892.   */
  2893.   window->screen=visual_info->screen;
  2894.   window->visual=visual_info->visual;
  2895.   window->class=visual_info->class;
  2896.   window->depth=visual_info->depth;
  2897.   window->visual_info=visual_info;
  2898.   window->map_info=map_info;
  2899.   window->pixel_info=pixel_info;
  2900.   window->font_info=font_info;
  2901.   window->cursor=XCreateFontCursor(display,XC_left_ptr);
  2902.   window->busy_cursor=XCreateFontCursor(display,XC_watch);
  2903.   window->name=(char *) NULL;
  2904.   window->geometry=(char *) NULL;
  2905.   window->icon_name=(char *) NULL;
  2906.   window->icon_geometry=resource_info->icon_geometry;
  2907.   window->clip_geometry=(char *) NULL;
  2908.   window->flags=PSize;
  2909.   window->x=0;
  2910.   window->y=0;
  2911.   window->width=1;
  2912.   window->height=1;
  2913.   window->min_width=1;
  2914.   window->min_height=1;
  2915.   window->width_inc=1;
  2916.   window->height_inc=1;
  2917.   window->border_width=resource_info->border_width;
  2918.   window->annotate_context=pixel_info->annotate_context;
  2919.   window->highlight_context=pixel_info->highlight_context;
  2920.   window->widget_context=pixel_info->widget_context;
  2921.   window->shadow_stipple=(Pixmap) NULL;
  2922.   window->highlight_stipple=(Pixmap) NULL;
  2923.   window->immutable=False;
  2924.   window->mask=CWBackingStore | CWBackPixel | CWBackPixmap | CWBitGravity |
  2925.     CWBorderPixel | CWColormap | CWCursor | CWDontPropagate | CWEventMask |
  2926.     CWOverrideRedirect | CWSaveUnder | CWWinGravity;
  2927.   window->attributes.background_pixel=pixel_info->background_color.pixel;
  2928.   window->attributes.background_pixmap=(Pixmap) NULL;
  2929.   window->attributes.backing_store=NotUseful;
  2930.   window->attributes.bit_gravity=ForgetGravity;
  2931.   window->attributes.border_pixel=pixel_info->border_color.pixel;
  2932.   window->attributes.colormap=map_info->colormap;
  2933.   window->attributes.cursor=window->cursor;
  2934.   window->attributes.do_not_propagate_mask=NoEventMask;
  2935.   window->attributes.event_mask=NoEventMask;
  2936.   window->attributes.override_redirect=False;
  2937.   window->attributes.save_under=False;
  2938.   window->attributes.win_gravity=NorthWestGravity;
  2939.   if (window->id == (Window) NULL)
  2940.     {
  2941.       window->id=(Window) NULL;
  2942.       window->ximage=(XImage *) NULL;
  2943.       window->pixmap=(Pixmap) NULL;
  2944.       window->mapped=False;
  2945.       window->stasis=False;
  2946.     }
  2947. }
  2948.  
  2949. /*
  2950. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2951. %                                                                             %
  2952. %                                                                             %
  2953. %                                                                             %
  2954. %   X H i g h l i g h t L i n e                                               %
  2955. %                                                                             %
  2956. %                                                                             %
  2957. %                                                                             %
  2958. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2959. %
  2960. %  Function XHighlightLine puts a border on the X server around a region
  2961. %  defined by highlight_info.
  2962. %
  2963. %  The format of the XHighlightLine routine is:
  2964. %
  2965. %    XHighlightLine(display,window,annotate_context,highlight_info)
  2966. %
  2967. %  A description of each parameter follows:
  2968. %
  2969. %    o display: Specifies a connection to an X server; returned from
  2970. %      XOpenDisplay.
  2971. %
  2972. %    o window: Specifies a pointer to a Window structure.
  2973. %
  2974. %    o annotate_context: Specifies a pointer to a GC structure.
  2975. %
  2976. %    o highlight_info: Specifies a pointer to a RectangleInfo structure.  It
  2977. %      contains the extents of any highlighting rectangle.
  2978. %
  2979. %
  2980. */
  2981. void XHighlightLine(display,window,annotate_context,highlight_info)
  2982. Display
  2983.   *display;
  2984.  
  2985. Window
  2986.   window;
  2987.  
  2988. GC
  2989.   annotate_context;
  2990.  
  2991. XSegment
  2992.   *highlight_info;
  2993. {
  2994.   XDrawLine(display,window,annotate_context,highlight_info->x1,
  2995.     highlight_info->y1,highlight_info->x2,highlight_info->y2);
  2996.   XDrawLine(display,window,annotate_context,highlight_info->x1,
  2997.     highlight_info->y1+2,highlight_info->x2,highlight_info->y2+2);
  2998. }
  2999.  
  3000. /*
  3001. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3002. %                                                                             %
  3003. %                                                                             %
  3004. %                                                                             %
  3005. %   X H i g h l i g h t R e g i o n                                           %
  3006. %                                                                             %
  3007. %                                                                             %
  3008. %                                                                             %
  3009. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3010. %
  3011. %  Function XHighlightRegion puts a border on the X server around a region
  3012. %  defined by highlight_info.
  3013. %
  3014. %  The format of the XHighlightRegion routine is:
  3015. %
  3016. %    XHighlightRegion(display,window,annotate_context,highlight_info)
  3017. %
  3018. %  A description of each parameter follows:
  3019. %
  3020. %    o display: Specifies a connection to an X server; returned from
  3021. %      XOpenDisplay.
  3022. %
  3023. %    o window: Specifies a pointer to a Window structure.
  3024. %
  3025. %    o annotate_context: Specifies a pointer to a GC structure.
  3026. %
  3027. %    o highlight_info: Specifies a pointer to a RectangleInfo structure.  It
  3028. %      contains the extents of any highlighting rectangle.
  3029. %
  3030. %
  3031. */
  3032. void XHighlightRegion(display,window,annotate_context,highlight_info)
  3033. Display
  3034.   *display;
  3035.  
  3036. Window
  3037.   window;
  3038.  
  3039. GC
  3040.   annotate_context;
  3041.  
  3042. RectangleInfo
  3043.   *highlight_info;
  3044. {
  3045.   if ((highlight_info->width < 4) || (highlight_info->height < 4))
  3046.     return;
  3047.   XDrawRectangle(display,window,annotate_context,highlight_info->x,
  3048.     highlight_info->y,highlight_info->width-1,highlight_info->height-1);
  3049.   XDrawRectangle(display,window,annotate_context,highlight_info->x+1,
  3050.     highlight_info->y+1,highlight_info->width-3,highlight_info->height-3);
  3051. }
  3052.  
  3053. /*
  3054. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3055. %                                                                             %
  3056. %                                                                             %
  3057. %                                                                             %
  3058. %   X L i s t C o l o r s                                                     %
  3059. %                                                                             %
  3060. %                                                                             %
  3061. %                                                                             %
  3062. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3063. %
  3064. %  Function XListColors reads the X client color database and returns a list
  3065. %  of colors contained in the database sorted in ascending alphabetic order.
  3066. %
  3067. %  The format of the XListColors function is:
  3068. %
  3069. %      filelist=XListColors(pattern,number_colors)
  3070. %
  3071. %  A description of each parameter follows:
  3072. %
  3073. %    o filelist: Function XListColors returns a list of colors contained
  3074. %      in the database.  If the database cannot be read, a NULL list is
  3075. %      returned.
  3076. %
  3077. %    o pattern: Specifies a pointer to a text string containing a pattern.
  3078. %
  3079. %    o number_colors:  This integer returns the number of colors in the list.
  3080. %
  3081. %
  3082. */
  3083. static int ColorCompare(x,y)
  3084. const void
  3085.   *x,
  3086.   *y;
  3087. {
  3088.   register char
  3089.     *p,
  3090.     *q;
  3091.  
  3092.   p=(char *) *((char **) x);
  3093.   q=(char *) *((char **) y);
  3094.   while ((*p != '\0') && (*q != '\0') && (*p == *q))
  3095.   {
  3096.     p++;
  3097.     q++;
  3098.   }
  3099.   return(*p-(*q));
  3100. }
  3101.  
  3102. char **XListColors(pattern,number_colors)
  3103. char
  3104.   *pattern;
  3105.  
  3106. int
  3107.   *number_colors;
  3108. {
  3109.   char
  3110.     color[MaxTextLength],
  3111.     **colorlist,
  3112.     text[MaxTextLength];
  3113.  
  3114.   FILE
  3115.     *database;
  3116.  
  3117.   int
  3118.     blue,
  3119.     count,
  3120.     green,
  3121.     red;
  3122.  
  3123.   unsigned int
  3124.     max_colors;
  3125.  
  3126.   /*
  3127.     Open database.
  3128.   */
  3129.   *number_colors=0;
  3130.   database=fopen(RGBColorDatabase,"r");
  3131.   if (database == (FILE *) NULL)
  3132.     return((char **) NULL);
  3133.   /*
  3134.     Allocate color list.
  3135.   */
  3136.   max_colors=2048;
  3137.   colorlist=(char **) malloc(max_colors*sizeof(char *));
  3138.   if (colorlist == (char **) NULL)
  3139.     {
  3140.       (void) fclose(database);
  3141.       return((char **) NULL);
  3142.     }
  3143.   while (fgets(text,MaxTextLength,database) != (char *) NULL)
  3144.   {
  3145.     count=sscanf(text,"%d %d %d %[^\n]\n",&red,&green,&blue,color);
  3146.     if (count != 4)
  3147.       continue;
  3148.     if (GlobExpression(color,pattern))
  3149.       {
  3150.         if (*number_colors >= max_colors)
  3151.           {
  3152.             max_colors<<=1;
  3153.             colorlist=(char **)
  3154.               realloc((char *) colorlist,max_colors*sizeof(char *));
  3155.             if (colorlist == (char **) NULL)
  3156.               {
  3157.                 (void) fclose(database);
  3158.                 return((char **) NULL);
  3159.               }
  3160.           }
  3161.         colorlist[*number_colors]=(char *) malloc(strlen(color)+1);
  3162.         if (colorlist[*number_colors] == (char *) NULL)
  3163.           break;
  3164.         (void) strcpy(colorlist[*number_colors],color);
  3165.         (*number_colors)++;
  3166.       }
  3167.   }
  3168.   (void) fclose(database);
  3169.   /*
  3170.     Sort colorlist in ascending order.
  3171.   */
  3172.   (void) qsort((void *) colorlist,*number_colors,sizeof(char **),ColorCompare);
  3173.   return(colorlist);
  3174. }
  3175.  
  3176. /*
  3177. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3178. %                                                                             %
  3179. %                                                                             %
  3180. %                                                                             %
  3181. %   X M a k e C u r s o r                                                     %
  3182. %                                                                             %
  3183. %                                                                             %
  3184. %                                                                             %
  3185. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3186. %
  3187. %  Function XMakeCursor creates a crosshairs X11 cursor.
  3188. %
  3189. %  The format of the XMakeCursor routine is:
  3190. %
  3191. %      XMakeCursor(display,window,colormap,background_color,foreground_color)
  3192. %
  3193. %  A description of each parameter follows:
  3194. %
  3195. %    o display: Specifies a connection to an X server;  returned from
  3196. %      XOpenDisplay.
  3197. %
  3198. %    o window: Specifies the ID of the window for which the cursor is
  3199. %      assigned.
  3200. %
  3201. %    o colormap: Specifies the ID of the colormap from which the background
  3202. %      and foreground color will be retrieved.
  3203. %
  3204. %    o background_color: Specifies the color to use for the cursor background.
  3205. %
  3206. %    o foreground_color: Specifies the color to use for the cursor foreground.
  3207. %
  3208. %
  3209. */
  3210. Cursor XMakeCursor(display,window,colormap,background_color,foreground_color)
  3211. Display
  3212.   *display;
  3213.  
  3214. Window
  3215.   window;
  3216.  
  3217. Colormap
  3218.   colormap;
  3219.  
  3220. char
  3221.   *background_color,
  3222.   *foreground_color;
  3223. {
  3224. #define scope_height 17
  3225. #define scope_x_hot 8
  3226. #define scope_y_hot 8
  3227. #define scope_width 17
  3228.  
  3229.   static unsigned char
  3230.     scope_bits[] =
  3231.     {
  3232.       0x80, 0x03, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02,
  3233.       0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x7f,
  3234.       0xfc, 0x01, 0x01, 0x00, 0x01, 0x7f, 0xfc, 0x01, 0x80, 0x02, 0x00,
  3235.       0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02,
  3236.       0x00, 0x80, 0x02, 0x00, 0x80, 0x03, 0x00
  3237.     };
  3238.  
  3239.   static unsigned char
  3240.     scope_mask_bits[] =
  3241.     {
  3242.       0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06,
  3243.       0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xff, 0xfe, 0x01, 0x7f,
  3244.       0xfc, 0x01, 0x03, 0x80, 0x01, 0x7f, 0xfc, 0x01, 0xff, 0xfe, 0x01,
  3245.       0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06, 0x00, 0xc0, 0x06,
  3246.       0x00, 0xc0, 0x07, 0x00, 0xc0, 0x07, 0x00
  3247.     };
  3248.  
  3249.   Cursor
  3250.     cursor;
  3251.  
  3252.   Pixmap
  3253.     mask,
  3254.     source;
  3255.  
  3256.   XColor
  3257.     background,
  3258.     foreground;
  3259.  
  3260.   source=XCreateBitmapFromData(display,window,(char *) scope_bits,scope_width,
  3261.     scope_height);
  3262.   mask=XCreateBitmapFromData(display,window,(char *) scope_mask_bits,
  3263.     scope_width,scope_height);
  3264.   if ((source == (Pixmap) NULL) || (mask == (Pixmap) NULL))
  3265.     Error("Unable to create pixmap",(char *) NULL);
  3266.   XParseColor(display,colormap,background_color,&background);
  3267.   XParseColor(display,colormap,foreground_color,&foreground);
  3268.   cursor=XCreatePixmapCursor(display,source,mask,&foreground,&background,
  3269.     scope_x_hot,scope_y_hot);
  3270.   XFreePixmap(display,source);
  3271.   XFreePixmap(display,mask);
  3272.   return(cursor);
  3273. }
  3274.  
  3275. /*
  3276. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3277. %                                                                             %
  3278. %                                                                             %
  3279. %                                                                             %
  3280. %   X M a k e I m a g e                                                       %
  3281. %                                                                             %
  3282. %                                                                             %
  3283. %                                                                             %
  3284. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3285. %
  3286. %  Function XMakeImage creates an X11 image.  If the image size differs from
  3287. %  the X11 image size, the image is first resized.
  3288. %
  3289. %  The format of the XMakeImage routine is:
  3290. %
  3291. %      status=XMakeImage(display,resource_info,window,image,width,height)
  3292. %
  3293. %  A description of each parameter follows:
  3294. %
  3295. %    o status: Function XMakeImage returns True if the X image is
  3296. %      successfully created.  False is returned is there is a memory shortage.
  3297. %
  3298. %    o display: Specifies a connection to an X server; returned from
  3299. %      XOpenDisplay.
  3300. %
  3301. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  3302. %
  3303. %    o window: Specifies a pointer to a XWindowInfo structure.
  3304. %
  3305. %    o image: Specifies a pointer to a Image structure;  returned from
  3306. %      ReadImage.
  3307. %
  3308. %    o width: Specifies the width in pixels of the rectangular area to
  3309. %      display.
  3310. %
  3311. %    o height: Specifies the height in pixels of the rectangular area to
  3312. %      display.
  3313. %
  3314. %
  3315. */
  3316. unsigned int XMakeImage(display,resource_info,window,image,width,height)
  3317. Display
  3318.   *display;
  3319.  
  3320. XResourceInfo
  3321.   *resource_info;
  3322.  
  3323. XWindowInfo
  3324.   *window;
  3325.  
  3326. Image
  3327.   *image;
  3328.  
  3329. unsigned int
  3330.   width,
  3331.   height;
  3332. {
  3333.   Image
  3334.     *transformed_image;
  3335.  
  3336.   int
  3337.     format;
  3338.  
  3339.   XImage
  3340.     *ximage;
  3341.  
  3342.   if ((window->width == 0) || (window->height == 0))
  3343.     return(False);
  3344.   /*
  3345.     Display busy cursor.
  3346.   */
  3347.   XDefineCursor(display,window->id,window->busy_cursor);
  3348.   XFlush(display);
  3349.   transformed_image=image;
  3350.   if (image != (Image *) NULL)
  3351.     {
  3352.       /*
  3353.         Apply user transforms to the image.
  3354.       */
  3355.       if (window->clip_geometry)
  3356.         {
  3357.           Image
  3358.             *clipped_image;
  3359.  
  3360.           RectangleInfo
  3361.             clip_info;
  3362.  
  3363.           /*
  3364.             Clip image.
  3365.           */
  3366.           (void) XParseGeometry(window->clip_geometry,&clip_info.x,&clip_info.y,
  3367.             &clip_info.width,&clip_info.height);
  3368.           transformed_image->orphan=True;
  3369.           clipped_image=ClipImage(transformed_image,&clip_info);
  3370.           transformed_image->orphan=False;
  3371.           if (transformed_image != image)
  3372.             DestroyImage(transformed_image);
  3373.           if (clipped_image == (Image *) NULL)
  3374.             return(False);
  3375.           transformed_image=clipped_image;
  3376.         }
  3377.       if ((width != transformed_image->columns) ||
  3378.           (height != transformed_image->rows))
  3379.         {
  3380.           Image
  3381.             *scaled_image;
  3382.  
  3383.           /*
  3384.             Scale image.
  3385.           */
  3386.           transformed_image->orphan=True;
  3387.           if (window->pixel_info->colors != 0)
  3388.             scaled_image=SampleImage(transformed_image,width,height);
  3389.           else
  3390.             scaled_image=ScaleImage(transformed_image,width,height);
  3391.           transformed_image->orphan=False;
  3392.           if (transformed_image != image)
  3393.             DestroyImage(transformed_image);
  3394.           if (scaled_image == (Image *) NULL)
  3395.             return(False);
  3396.           transformed_image=scaled_image;
  3397.         }
  3398.       width=transformed_image->columns;
  3399.       height=transformed_image->rows;
  3400.     }
  3401.   /*
  3402.     Create X image.
  3403.   */
  3404.   format=(window->depth == 1) ? XYBitmap : ZPixmap;
  3405.   ximage=XCreateImage(display,window->visual,window->depth,format,0,
  3406.     (char *) NULL,width,height,XBitmapPad(display),0);
  3407.   if (ximage == (XImage *) NULL)
  3408.     {
  3409.       /*
  3410.         Unable to create X image.
  3411.       */
  3412.       XDefineCursor(display,window->id,window->cursor);
  3413.       return(False);
  3414.     }
  3415.   if (resource_info->debug)
  3416.     {
  3417.       (void) fprintf(stderr,"XImage:\n");
  3418.       (void) fprintf(stderr,"  width, height: %dx%d\n",ximage->width,
  3419.         ximage->height);
  3420.       (void) fprintf(stderr,"  format: %d\n",ximage->format);
  3421.       (void) fprintf(stderr,"  byte order: %d\n",ximage->byte_order);
  3422.       (void) fprintf(stderr,"  bitmap unit, bit order, pad: %d %d %d\n",
  3423.         ximage->bitmap_unit,ximage->bitmap_bit_order,ximage->bitmap_pad);
  3424.       (void) fprintf(stderr,"  depth: %d\n",ximage->depth);
  3425.       (void) fprintf(stderr,"  bytes per line: %d\n",ximage->bytes_per_line);
  3426.       (void) fprintf(stderr,"  bits per pixel: %d\n",ximage->bits_per_pixel);
  3427.       (void) fprintf(stderr,"  red, green, blue masks: 0x%lx 0x%lx 0x%lx\n",
  3428.         ximage->red_mask,ximage->green_mask,ximage->blue_mask);
  3429.     }
  3430.   /*
  3431.     Allocate X image pixel data.
  3432.   */
  3433.   if (ximage->format == XYBitmap)
  3434.     ximage->data=(char *)
  3435.       malloc(ximage->bytes_per_line*ximage->height*ximage->depth);
  3436.   else
  3437.     ximage->data=(char *) malloc(ximage->bytes_per_line*ximage->height);
  3438.   if (ximage->data == (char *) NULL)
  3439.     {
  3440.       /*
  3441.         Unable to allocate pixel data.
  3442.       */
  3443.       XDestroyImage(ximage);
  3444.       XDefineCursor(display,window->id,window->cursor);
  3445.       return(False);
  3446.     }
  3447.   if (window->ximage != (XImage *) NULL)
  3448.     XDestroyImage(window->ximage);
  3449.   window->ximage=ximage;
  3450.   window->stasis=False;
  3451.   if (image == (Image *) NULL)
  3452.     {
  3453.       XDefineCursor(display,window->id,window->cursor);
  3454.       return(True);
  3455.     }
  3456.   /*
  3457.     Convert runlength-encoded pixels to X image data.
  3458.   */
  3459.   if ((ximage->byte_order == LSBFirst) ||
  3460.       ((ximage->format == XYBitmap) && (ximage->bitmap_bit_order == LSBFirst)))
  3461.     XMakeImageLSBFirst(window,transformed_image,ximage);
  3462.   else
  3463.     XMakeImageMSBFirst(window,transformed_image,ximage);
  3464.   if (transformed_image != image)
  3465.     DestroyImage(transformed_image);
  3466.   /*
  3467.     Restore cursor.
  3468.   */
  3469.   XDefineCursor(display,window->id,window->cursor);
  3470.   return(True);
  3471. }
  3472.  
  3473. /*
  3474. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3475. %                                                                             %
  3476. %                                                                             %
  3477. %                                                                             %
  3478. %   X M a k e I m a g e L S B F i r s t                                       %
  3479. %                                                                             %
  3480. %                                                                             %
  3481. %                                                                             %
  3482. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3483. %
  3484. %  Function XMakeImageLSBFirst initializes the pixel data of an X11 Image.
  3485. %  The X image pixels are copied in least-significant bit and byte first
  3486. %  order.  The server's scanline pad is respected.  Rather than using one or
  3487. %  two general cases, many special cases are found here to help speed up the
  3488. %  image conversion.
  3489. %
  3490. %  The format of the XMakeImageLSBFirst routine is:
  3491. %
  3492. %      XMakeImageLSBFirst(window,image,ximage)
  3493. %
  3494. %  A description of each parameter follows:
  3495. %
  3496. %    o window: Specifies a pointer to a XWindowInfo structure.
  3497. %
  3498. %    o image: Specifies a pointer to a Image structure;  returned from
  3499. %      ReadImage.
  3500. %
  3501. %    o ximage: Specifies a pointer to a XImage structure;  returned from
  3502. %      XCreateImage.
  3503. %
  3504. %
  3505. */
  3506. static void XMakeImageLSBFirst(window,image,ximage)
  3507. XWindowInfo
  3508.   *window;
  3509.  
  3510. Image
  3511.   *image;
  3512.  
  3513. XImage
  3514.   *ximage;
  3515. {
  3516.   register int
  3517.     i,
  3518.     j,
  3519.     x;
  3520.  
  3521.   register RunlengthPacket
  3522.     *p;
  3523.  
  3524.   register unsigned char
  3525.     *q;
  3526.  
  3527.   register unsigned long
  3528.     pixel;
  3529.  
  3530.   unsigned int
  3531.     scanline_pad;
  3532.  
  3533.   unsigned long
  3534.     *pixels;
  3535.  
  3536.   pixels=window->pixel_info->pixels;
  3537.   p=image->pixels;
  3538.   q=(unsigned char *) ximage->data;
  3539.   x=0;
  3540.   if (ximage->format == XYBitmap)
  3541.     {
  3542.       register unsigned char
  3543.         background,
  3544.         bit,
  3545.         byte,
  3546.         foreground;
  3547.  
  3548.       register unsigned short
  3549.         polarity;
  3550.  
  3551.       /*
  3552.         Convert image to big-endian bitmap.
  3553.       */
  3554.       background=(Intensity(window->pixel_info->foreground_color) <
  3555.         Intensity(window->pixel_info->background_color) ? 0x80 : 0x00);
  3556.       foreground=(Intensity(window->pixel_info->background_color) <
  3557.         Intensity(window->pixel_info->foreground_color) ? 0x80 : 0x00);
  3558.       polarity=Intensity(image->colormap[0]) < Intensity(image->colormap[1]);
  3559.       scanline_pad=ximage->bytes_per_line-(ximage->width >> 3);
  3560.       bit=0;
  3561.       byte=0;
  3562.       for (i=0; i < image->packets; i++)
  3563.       {
  3564.         for (j=0; j <= ((int) p->length); j++)
  3565.         {
  3566.           byte>>=1;
  3567.           if (p->index == polarity)
  3568.             byte|=foreground;
  3569.           else
  3570.             byte|=background;
  3571.           bit++;
  3572.           if (bit == 8)
  3573.             {
  3574.               *q++=byte;
  3575.               bit=0;
  3576.               byte=0;
  3577.             }
  3578.           x++;
  3579.           if (x == ximage->width)
  3580.             {
  3581.               /*
  3582.                 Advance to the next scanline.
  3583.               */
  3584.               if (bit != 0)
  3585.                 *q=byte >> (8-bit);
  3586.               q+=scanline_pad;
  3587.               bit=0;
  3588.               byte=0;
  3589.               x=0;
  3590.             }
  3591.         }
  3592.         p++;
  3593.       }
  3594.     }
  3595.   else
  3596.     {
  3597.       XStandardColormap
  3598.         *map_info;
  3599.  
  3600.       /*
  3601.         Convert image to little-endian color-mapped X image.
  3602.       */
  3603.       map_info=window->map_info;
  3604.       scanline_pad=ximage->bytes_per_line-
  3605.         ((ximage->width*ximage->bits_per_pixel) >> 3);
  3606.       if (window->pixel_info->colors != 0)
  3607.         switch (ximage->bits_per_pixel)
  3608.         {
  3609.           case 2:
  3610.           {
  3611.             register unsigned int
  3612.               nibble;
  3613.  
  3614.             /*
  3615.               Convert to 2 bit color-mapped X image.
  3616.             */
  3617.             nibble=0;
  3618.             for (i=0; i < image->packets; i++)
  3619.             {
  3620.               pixel=pixels[p->index] & 0xf;
  3621.               for (j=0; j <= ((int) p->length); j++)
  3622.               {
  3623.                 switch (nibble)
  3624.                 {
  3625.                   case 0:
  3626.                   {
  3627.                     *q=(unsigned char) pixel;
  3628.                     nibble++;
  3629.                     break;
  3630.                   }
  3631.                   case 1:
  3632.                   {
  3633.                     *q|=(unsigned char) (pixel << 2);
  3634.                     nibble++;
  3635.                     break;
  3636.                   }
  3637.                   case 2:
  3638.                   {
  3639.                     *q|=(unsigned char) (pixel << 4);
  3640.                     nibble++;
  3641.                     break;
  3642.                   }
  3643.                   case 3:
  3644.                   {
  3645.                     *q|=(unsigned char) (pixel << 6);
  3646.                     q++;
  3647.                     nibble=0;
  3648.                     break;
  3649.                   }
  3650.                 }
  3651.                 x++;
  3652.                 if (x == ximage->width)
  3653.                   {
  3654.                     x=0;
  3655.                     nibble=0;
  3656.                     q+=scanline_pad;
  3657.                   }
  3658.               }
  3659.               p++;
  3660.             }
  3661.             break;
  3662.           }
  3663.           case 4:
  3664.           {
  3665.             register unsigned int
  3666.               nibble;
  3667.  
  3668.             /*
  3669.               Convert to 4 bit color-mapped X image.
  3670.             */
  3671.             nibble=0;
  3672.             for (i=0; i < image->packets; i++)
  3673.             {
  3674.               pixel=pixels[p->index] & 0xf;
  3675.               for (j=0; j <= ((int) p->length); j++)
  3676.               {
  3677.                 switch (nibble)
  3678.                 {
  3679.                   case 0:
  3680.                   {
  3681.                     *q=(unsigned char) pixel;
  3682.                     nibble++;
  3683.                     break;
  3684.                   }
  3685.                   case 1:
  3686.                   {
  3687.                     *q|=(unsigned char) (pixel << 4);
  3688.                     q++;
  3689.                     nibble=0;
  3690.                     break;
  3691.                   }
  3692.                 }
  3693.                 x++;
  3694.                 if (x == ximage->width)
  3695.                   {
  3696.                     x=0;
  3697.                     nibble=0;
  3698.                     q+=scanline_pad;
  3699.                   }
  3700.               }
  3701.               p++;
  3702.             }
  3703.             break;
  3704.           }
  3705.           case 6:
  3706.           case 8:
  3707.           {
  3708.             /*
  3709.               Convert to 8 bit color-mapped X image.
  3710.             */
  3711.             for (i=0; i < image->packets; i++)
  3712.             {
  3713.               pixel=pixels[p->index];
  3714.               for (j=0; j <= ((int) p->length); j++)
  3715.               {
  3716.                 *q++=(unsigned char) pixel;
  3717.                 x++;
  3718.                 if (x == ximage->width)
  3719.                   {
  3720.                     x=0;
  3721.                     q+=scanline_pad;
  3722.                   }
  3723.               }
  3724.               p++;
  3725.             }
  3726.             break;
  3727.           }
  3728.           default:
  3729.           {
  3730.             register int
  3731.               k;
  3732.  
  3733.             register unsigned int
  3734.               bytes_per_pixel;
  3735.  
  3736.             unsigned char
  3737.               channel[sizeof(unsigned long)];
  3738.  
  3739.             /*
  3740.               Convert to multi-byte color-mapped X image.
  3741.             */
  3742.             bytes_per_pixel=ximage->bits_per_pixel >> 3;
  3743.             for (i=0; i < image->packets; i++)
  3744.             {
  3745.               pixel=pixels[p->index];
  3746.               for (k=0; k < bytes_per_pixel; k++)
  3747.               {
  3748.                 channel[k]=(unsigned char) pixel;
  3749.                 pixel>>=8;
  3750.               }
  3751.               for (j=0; j <= ((int) p->length); j++)
  3752.               {
  3753.                 for (k=0; k < bytes_per_pixel; k++)
  3754.                   *q++=channel[k];
  3755.                 x++;
  3756.                 if (x == ximage->width)
  3757.                   {
  3758.                     x=0;
  3759.                     q+=scanline_pad;
  3760.                   }
  3761.               }
  3762.               p++;
  3763.             }
  3764.             break;
  3765.           }
  3766.         }
  3767.       else
  3768.         {
  3769.           /*
  3770.             Convert image to little-endian continuous-tone X image.
  3771.           */
  3772.           switch (ximage->bits_per_pixel)
  3773.           {
  3774.             case 2:
  3775.             {
  3776.               register unsigned int
  3777.                 nibble;
  3778.  
  3779.               /*
  3780.                 Convert to contiguous 2 bit continuous-tone X image.
  3781.               */
  3782.               nibble=0;
  3783.               for (i=0; i < image->packets; i++)
  3784.               {
  3785.                 pixel=XStandardPixel(map_info,(*p),8);
  3786.                 pixel&=0xf;
  3787.                 for (j=0; j <= ((int) p->length); j++)
  3788.                 {
  3789.                   switch (nibble)
  3790.                   {
  3791.                     case 0:
  3792.                     {
  3793.                       *q=(unsigned char) pixel;
  3794.                       nibble++;
  3795.                       break;
  3796.                     }
  3797.                     case 1:
  3798.                     {
  3799.                       *q|=(unsigned char) (pixel << 2);
  3800.                       nibble++;
  3801.                       break;
  3802.                     }
  3803.                     case 2:
  3804.                     {
  3805.                       *q|=(unsigned char) (pixel << 4);
  3806.                       nibble++;
  3807.                       break;
  3808.                     }
  3809.                     case 3:
  3810.                     {
  3811.                       *q|=(unsigned char) (pixel << 6);
  3812.                       q++;
  3813.                       nibble=0;
  3814.                       break;
  3815.                     }
  3816.                   }
  3817.                   x++;
  3818.                   if (x == ximage->width)
  3819.                     {
  3820.                       x=0;
  3821.                       nibble=0;
  3822.                       q+=scanline_pad;
  3823.                     }
  3824.                 }
  3825.                 p++;
  3826.               }
  3827.               break;
  3828.             }
  3829.             case 4:
  3830.             {
  3831.               register unsigned int
  3832.                 nibble;
  3833.  
  3834.               /*
  3835.                 Convert to contiguous 4 bit continuous-tone X image.
  3836.               */
  3837.               nibble=0;
  3838.               for (i=0; i < image->packets; i++)
  3839.               {
  3840.                 pixel=XStandardPixel(map_info,(*p),8);
  3841.                 pixel&=0xf;
  3842.                 for (j=0; j <= ((int) p->length); j++)
  3843.                 {
  3844.                   switch (nibble)
  3845.                   {
  3846.                     case 0:
  3847.                     {
  3848.                       *q=(unsigned char) pixel;
  3849.                       nibble++;
  3850.                       break;
  3851.                     }
  3852.                     case 1:
  3853.                     {
  3854.                       *q|=(unsigned char) (pixel << 4);
  3855.                       q++;
  3856.                       nibble=0;
  3857.                       break;
  3858.                     }
  3859.                   }
  3860.                   x++;
  3861.                   if (x == ximage->width)
  3862.                     {
  3863.                       x=0;
  3864.                       nibble=0;
  3865.                       q+=scanline_pad;
  3866.                     }
  3867.                 }
  3868.                 p++;
  3869.               }
  3870.               break;
  3871.             }
  3872.             case 6:
  3873.             case 8:
  3874.             {
  3875.               /*
  3876.                 Convert to contiguous 8 bit continuous-tone X image.
  3877.               */
  3878.               for (i=0; i < image->packets; i++)
  3879.               {
  3880.                 pixel=XStandardPixel(map_info,(*p),8);
  3881.                 for (j=0; j <= ((int) p->length); j++)
  3882.                 {
  3883.                   *q++=(unsigned char) pixel;
  3884.                   x++;
  3885.                   if (x == ximage->width)
  3886.                     {
  3887.                       x=0;
  3888.                       q+=scanline_pad;
  3889.                     }
  3890.                 }
  3891.                 p++;
  3892.               }
  3893.               break;
  3894.             }
  3895.             default:
  3896.             {
  3897.               if ((ximage->bits_per_pixel == 32) &&
  3898.                   (map_info->red_max == 255) &&
  3899.                   (map_info->green_max == 255) &&
  3900.                   (map_info->blue_max == 255) &&
  3901.                   (map_info->red_mult == 65536) &&
  3902.                   (map_info->green_mult == 256) &&
  3903.                   (map_info->blue_mult == 1))
  3904.                 {
  3905.                   /*
  3906.                     Convert to 32 bit continuous-tone X image.
  3907.                   */
  3908.                   for (i=0; i < image->packets; i++)
  3909.                   {
  3910.                     for (j=0; j <= ((int) p->length); j++)
  3911.                     {
  3912.                       *q++=p->blue;
  3913.                       *q++=p->green;
  3914.                       *q++=p->red;
  3915.                       *q++=0;
  3916.                     }
  3917.                     p++;
  3918.                   }
  3919.                 }
  3920.               else
  3921.                 {
  3922.                   register int
  3923.                     k;
  3924.  
  3925.                   register unsigned int
  3926.                     bytes_per_pixel;
  3927.  
  3928.                   unsigned char
  3929.                     channel[sizeof(unsigned long)];
  3930.  
  3931.                   /*
  3932.                     Convert to multi-byte continuous-tone X image.
  3933.                   */
  3934.                   bytes_per_pixel=ximage->bits_per_pixel >> 3;
  3935.                   for (i=0; i < image->packets; i++)
  3936.                   {
  3937.                     pixel=XStandardPixel(map_info,(*p),8);
  3938.                     for (k=0; k < bytes_per_pixel; k++)
  3939.                     {
  3940.                       channel[k]=(unsigned char) pixel;
  3941.                       pixel>>=8;
  3942.                     }
  3943.                     for (j=0; j <= ((int) p->length); j++)
  3944.                     {
  3945.                       for (k=0; k < bytes_per_pixel; k++)
  3946.                         *q++=channel[k];
  3947.                       x++;
  3948.                       if (x == ximage->width)
  3949.                         {
  3950.                           x=0;
  3951.                           q+=scanline_pad;
  3952.                         }
  3953.                     }
  3954.                     p++;
  3955.                   }
  3956.                 }
  3957.               break;
  3958.             }
  3959.           }
  3960.         }
  3961.     }
  3962. }
  3963.  
  3964. /*
  3965. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3966. %                                                                             %
  3967. %                                                                             %
  3968. %                                                                             %
  3969. %   X M a k e I m a g e M S B F i r s t                                       %
  3970. %                                                                             %
  3971. %                                                                             %
  3972. %                                                                             %
  3973. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3974. %
  3975. %  Function XMakeImageMSBFirst initializes the pixel data of an X11 Image.
  3976. %  The X image pixels are copied in most-significant bit and byte first order.
  3977. %  The server's scanline pad is also resprected. Rather than using one or two
  3978. %  general cases, many special cases are found here to help speed up the image
  3979. %  conversion.
  3980. %
  3981. %  The format of the XMakeImageMSBFirst routine is:
  3982. %
  3983. %      XMakeImageMSBFirst(window,image,ximage)
  3984. %
  3985. %  A description of each parameter follows:
  3986. %
  3987. %    o window: Specifies a pointer to a XWindowInfo structure.
  3988. %
  3989. %    o image: Specifies a pointer to a Image structure;  returned from
  3990. %      ReadImage.
  3991. %
  3992. %    o ximage: Specifies a pointer to a XImage structure;  returned from
  3993. %      XCreateImage.
  3994. %
  3995. %
  3996. */
  3997. static void XMakeImageMSBFirst(window,image,ximage)
  3998. XWindowInfo
  3999.   *window;
  4000.  
  4001. Image
  4002.   *image;
  4003.  
  4004. XImage
  4005.   *ximage;
  4006. {
  4007.   register int
  4008.     i,
  4009.     j,
  4010.     x;
  4011.  
  4012.   register RunlengthPacket
  4013.     *p;
  4014.  
  4015.   register unsigned char
  4016.     *q;
  4017.  
  4018.   register unsigned long
  4019.     pixel;
  4020.  
  4021.   unsigned int
  4022.     scanline_pad;
  4023.  
  4024.   unsigned long
  4025.     *pixels;
  4026.  
  4027.   pixels=window->pixel_info->pixels;
  4028.   p=image->pixels;
  4029.   q=(unsigned char *) ximage->data;
  4030.   x=0;
  4031.   if (ximage->format == XYBitmap)
  4032.     {
  4033.       register unsigned char
  4034.         background,
  4035.         bit,
  4036.         byte,
  4037.         foreground;
  4038.  
  4039.       register unsigned short
  4040.         polarity;
  4041.  
  4042.       /*
  4043.         Convert image to big-endian bitmap.
  4044.       */
  4045.       background=(Intensity(window->pixel_info->foreground_color) <
  4046.         Intensity(window->pixel_info->background_color) ? 0x01 : 0x00);
  4047.       foreground=(Intensity(window->pixel_info->background_color) <
  4048.         Intensity(window->pixel_info->foreground_color) ? 0x01 : 0x00);
  4049.       polarity=Intensity(image->colormap[0]) < Intensity(image->colormap[1]);
  4050.       scanline_pad=ximage->bytes_per_line-(ximage->width >> 3);
  4051.       bit=0;
  4052.       byte=0;
  4053.       for (i=0; i < image->packets; i++)
  4054.       {
  4055.         for (j=0; j <= ((int) p->length); j++)
  4056.         {
  4057.           byte<<=1;
  4058.           if (p->index == polarity)
  4059.             byte|=foreground;
  4060.           else
  4061.             byte|=background;
  4062.           bit++;
  4063.           if (bit == 8)
  4064.             {
  4065.               *q++=byte;
  4066.               bit=0;
  4067.               byte=0;
  4068.             }
  4069.           x++;
  4070.           if (x == ximage->width)
  4071.             {
  4072.               /*
  4073.                 Advance to the next scanline.
  4074.               */
  4075.               if (bit != 0)
  4076.                 *q=byte << (8-bit);
  4077.               q+=scanline_pad;
  4078.               bit=0;
  4079.               byte=0;
  4080.               x=0;
  4081.             }
  4082.         }
  4083.         p++;
  4084.       }
  4085.     }
  4086.   else
  4087.     {
  4088.       XStandardColormap
  4089.         *map_info;
  4090.  
  4091.       /*
  4092.         Convert image to big-endian X image.
  4093.       */
  4094.       map_info=window->map_info;
  4095.       scanline_pad=ximage->bytes_per_line-
  4096.         ((ximage->width*ximage->bits_per_pixel) >> 3);
  4097.       if (window->pixel_info->colors != 0)
  4098.         switch (ximage->bits_per_pixel)
  4099.         {
  4100.           case 2:
  4101.           {
  4102.             register unsigned int
  4103.               nibble;
  4104.  
  4105.             /*
  4106.               Convert to 2 bit color-mapped X image.
  4107.             */
  4108.             nibble=0;
  4109.             for (i=0; i < image->packets; i++)
  4110.             {
  4111.               pixel=pixels[p->index] & 0xf;
  4112.               for (j=0; j <= ((int) p->length); j++)
  4113.               {
  4114.                 switch (nibble)
  4115.                 {
  4116.                   case 0:
  4117.                   {
  4118.                     *q=(unsigned char) (pixel << 6);
  4119.                     nibble++;
  4120.                     break;
  4121.                   }
  4122.                   case 1:
  4123.                   {
  4124.                     *q|=(unsigned char) (pixel << 4);
  4125.                     nibble++;
  4126.                     break;
  4127.                   }
  4128.                   case 2:
  4129.                   {
  4130.                     *q|=(unsigned char) (pixel << 2);
  4131.                     nibble++;
  4132.                     break;
  4133.                   }
  4134.                   case 3:
  4135.                   {
  4136.                     *q|=(unsigned char) pixel;
  4137.                     q++;
  4138.                     nibble=0;
  4139.                     break;
  4140.                   }
  4141.                 }
  4142.                 x++;
  4143.                 if (x == ximage->width)
  4144.                   {
  4145.                     x=0;
  4146.                     nibble=0;
  4147.                     q+=scanline_pad;
  4148.                   }
  4149.               }
  4150.               p++;
  4151.             }
  4152.             break;
  4153.           }
  4154.           case 4:
  4155.           {
  4156.             register unsigned int
  4157.               nibble;
  4158.  
  4159.             /*
  4160.               Convert to 4 bit color-mapped X image.
  4161.             */
  4162.             nibble=0;
  4163.             for (i=0; i < image->packets; i++)
  4164.             {
  4165.               pixel=pixels[p->index] & 0xf;
  4166.               for (j=0; j <= ((int) p->length); j++)
  4167.               {
  4168.                 switch (nibble)
  4169.                 {
  4170.                   case 0:
  4171.                   {
  4172.                     *q=(unsigned char) (pixel << 4);
  4173.                     nibble++;
  4174.                     break;
  4175.                   }
  4176.                   case 1:
  4177.                   {
  4178.                     *q|=(unsigned char) pixel;
  4179.                     q++;
  4180.                     nibble=0;
  4181.                     break;
  4182.                   }
  4183.                 }
  4184.                 x++;
  4185.                 if (x == ximage->width)
  4186.                   {
  4187.                     x=0;
  4188.                     nibble=0;
  4189.                     q+=scanline_pad;
  4190.                   }
  4191.               }
  4192.               p++;
  4193.             }
  4194.             break;
  4195.           }
  4196.           case 8:
  4197.           {
  4198.             /*
  4199.               Convert to 8 bit color-mapped X image.
  4200.             */
  4201.             for (i=0; i < image->packets; i++)
  4202.             {
  4203.               pixel=pixels[p->index];
  4204.               for (j=0; j <= ((int) p->length); j++)
  4205.               {
  4206.                 *q++=(unsigned char) pixel;
  4207.                 x++;
  4208.                 if (x == ximage->width)
  4209.                   {
  4210.                     x=0;
  4211.                     q+=scanline_pad;
  4212.                   }
  4213.               }
  4214.               p++;
  4215.             }
  4216.             break;
  4217.           }
  4218.           default:
  4219.           {
  4220.             register int
  4221.               k;
  4222.  
  4223.             register unsigned int
  4224.               bytes_per_pixel;
  4225.  
  4226.             unsigned char
  4227.               channel[sizeof(unsigned long)];
  4228.  
  4229.             /*
  4230.               Convert to 8 bit color-mapped X image.
  4231.             */
  4232.             bytes_per_pixel=ximage->bits_per_pixel >> 3;
  4233.             for (i=0; i < image->packets; i++)
  4234.             {
  4235.               pixel=pixels[p->index];
  4236.               for (k=bytes_per_pixel-1; k >= 0; k--)
  4237.               {
  4238.                 channel[k]=(unsigned char) pixel;
  4239.                 pixel>>=8;
  4240.               }
  4241.               for (j=0; j <= ((int) p->length); j++)
  4242.               {
  4243.                 for (k=0; k < bytes_per_pixel; k++)
  4244.                   *q++=channel[k];
  4245.                 x++;
  4246.                 if (x == ximage->width)
  4247.                   {
  4248.                     x=0;
  4249.                     q+=scanline_pad;
  4250.                   }
  4251.               }
  4252.               p++;
  4253.             }
  4254.             break;
  4255.           }
  4256.         }
  4257.       else
  4258.         {
  4259.           /*
  4260.             Convert to big-endian continuous-tone X image.
  4261.           */
  4262.           switch (ximage->bits_per_pixel)
  4263.           {
  4264.             case 2:
  4265.             {
  4266.               register unsigned int
  4267.                 nibble;
  4268.  
  4269.               /*
  4270.                 Convert to 4 bit continuous-tone X image.
  4271.               */
  4272.               nibble=0;
  4273.               for (i=0; i < image->packets; i++)
  4274.               {
  4275.                 pixel=XStandardPixel(map_info,(*p),8);
  4276.                 pixel&=0xf;
  4277.                 for (j=0; j <= ((int) p->length); j++)
  4278.                 {
  4279.                   switch (nibble)
  4280.                   {
  4281.                     case 0:
  4282.                     {
  4283.                       *q=(unsigned char) (pixel << 6);
  4284.                       nibble++;
  4285.                       break;
  4286.                     }
  4287.                     case 1:
  4288.                     {
  4289.                       *q|=(unsigned char) (pixel << 4);
  4290.                       nibble++;
  4291.                       break;
  4292.                     }
  4293.                     case 2:
  4294.                     {
  4295.                       *q|=(unsigned char) (pixel << 2);
  4296.                       nibble++;
  4297.                       break;
  4298.                     }
  4299.                     case 3:
  4300.                     {
  4301.                       *q|=(unsigned char) pixel;
  4302.                       q++;
  4303.                       nibble=0;
  4304.                       break;
  4305.                     }
  4306.                   }
  4307.                   x++;
  4308.                   if (x == ximage->width)
  4309.                     {
  4310.                       x=0;
  4311.                       nibble=0;
  4312.                       q+=scanline_pad;
  4313.                     }
  4314.                 }
  4315.                 p++;
  4316.               }
  4317.               break;
  4318.             }
  4319.             case 4:
  4320.             {
  4321.               register unsigned int
  4322.                 nibble;
  4323.  
  4324.               /*
  4325.                 Convert to 4 bit continuous-tone X image.
  4326.               */
  4327.               nibble=0;
  4328.               for (i=0; i < image->packets; i++)
  4329.               {
  4330.                 pixel=XStandardPixel(map_info,(*p),8);
  4331.                 pixel&=0xf;
  4332.                 for (j=0; j <= ((int) p->length); j++)
  4333.                 {
  4334.                   switch (nibble)
  4335.                   {
  4336.                     case 0:
  4337.                     {
  4338.                       *q=(unsigned char) (pixel << 4);
  4339.                       nibble++;
  4340.                       break;
  4341.                     }
  4342.                     case 1:
  4343.                     {
  4344.                       *q|=(unsigned char) pixel;
  4345.                       q++;
  4346.                       nibble=0;
  4347.                       break;
  4348.                     }
  4349.                   }
  4350.                   x++;
  4351.                   if (x == ximage->width)
  4352.                     {
  4353.                       x=0;
  4354.                       nibble=0;
  4355.                       q+=scanline_pad;
  4356.                     }
  4357.                 }
  4358.                 p++;
  4359.               }
  4360.               break;
  4361.             }
  4362.             case 8:
  4363.             {
  4364.               /*
  4365.                 Convert to 8 bit continuous-tone X image.
  4366.               */
  4367.               for (i=0; i < image->packets; i++)
  4368.               {
  4369.                 pixel=XStandardPixel(map_info,(*p),8);
  4370.                 for (j=0; j <= ((int) p->length); j++)
  4371.                 {
  4372.                   *q++=(unsigned char) pixel;
  4373.                   x++;
  4374.                   if (x == ximage->width)
  4375.                     {
  4376.                       x=0;
  4377.                       q+=scanline_pad;
  4378.                     }
  4379.                 }
  4380.                 p++;
  4381.               }
  4382.               break;
  4383.             }
  4384.             default:
  4385.             {
  4386.               if ((ximage->bits_per_pixel == 32) &&
  4387.                   (map_info->red_max == 255) &&
  4388.                   (map_info->green_max == 255) &&
  4389.                   (map_info->blue_max == 255) &&
  4390.                   (map_info->red_mult == 65536) &&
  4391.                   (map_info->green_mult == 256) &&
  4392.                   (map_info->blue_mult == 1))
  4393.                 {
  4394.                   /*
  4395.                     Convert to 32 bit continuous-tone X image.
  4396.                   */
  4397.                   for (i=0; i < image->packets; i++)
  4398.                   {
  4399.                     for (j=0; j <= ((int) p->length); j++)
  4400.                     {
  4401.                       *q++=0;
  4402.                       *q++=p->red;
  4403.                       *q++=p->green;
  4404.                       *q++=p->blue;
  4405.                     }
  4406.                     p++;
  4407.                   }
  4408.                 }
  4409.               else
  4410.                 {
  4411.                   register int
  4412.                     k;
  4413.  
  4414.                   register unsigned int
  4415.                     bytes_per_pixel;
  4416.  
  4417.                   unsigned char
  4418.                     channel[sizeof(unsigned long)];
  4419.  
  4420.                   /*
  4421.                     Convert to multi-byte continuous-tone X image.
  4422.                   */
  4423.                   bytes_per_pixel=ximage->bits_per_pixel >> 3;
  4424.                   for (i=0; i < image->packets; i++)
  4425.                   {
  4426.                     pixel=XStandardPixel(map_info,(*p),8);
  4427.                     for (k=bytes_per_pixel-1; k >= 0; k--)
  4428.                     {
  4429.                       channel[k]=(unsigned char) pixel;
  4430.                       pixel>>=8;
  4431.                     }
  4432.                     for (j=0; j <= ((int) p->length); j++)
  4433.                     {
  4434.                       for (k=0; k < bytes_per_pixel; k++)
  4435.                         *q++=channel[k];
  4436.                       x++;
  4437.                       if (x == ximage->width)
  4438.                         {
  4439.                           x=0;
  4440.                           q+=scanline_pad;
  4441.                         }
  4442.                     }
  4443.                     p++;
  4444.                   }
  4445.                 }
  4446.               break;
  4447.             }
  4448.           }
  4449.         }
  4450.     }
  4451. }
  4452.  
  4453. /*
  4454. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4455. %                                                                             %
  4456. %                                                                             %
  4457. %                                                                             %
  4458. %   X M a k e M a g n i f y I m a g e                                         %
  4459. %                                                                             %
  4460. %                                                                             %
  4461. %                                                                             %
  4462. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4463. %
  4464. %  Function XMakeMagnifyImage magnifies a region of an X image and displays it.
  4465. %
  4466. %  The format of the XMakeMagnifyImage routine is:
  4467. %
  4468. %      XMakeMagnifyImage(display,resource_info,window)
  4469. %
  4470. %  A description of each parameter follows:
  4471. %
  4472. %    o display: Specifies a connection to an X server;  returned from
  4473. %      XOpenDisplay.
  4474. %
  4475. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  4476. %
  4477. %    o window: Specifies a pointer to a XWindows structure.
  4478. %
  4479. %
  4480. */
  4481. void XMakeMagnifyImage(display,resource_info,window)
  4482. Display
  4483.   *display;
  4484.  
  4485. XResourceInfo
  4486.   *resource_info;
  4487.  
  4488. XWindows
  4489.   *window;
  4490. {
  4491.   register int
  4492.     x,
  4493.     y;
  4494.  
  4495.   register unsigned char
  4496.     *p,
  4497.     *q;
  4498.  
  4499.   register unsigned int
  4500.     j,
  4501.     k,
  4502.     l;
  4503.  
  4504.   static char
  4505.     text[MaxTextLength];
  4506.  
  4507.   static unsigned int
  4508.     previous_magnify=0;
  4509.  
  4510.   static XWindowInfo
  4511.     magnify_window;
  4512.  
  4513.   unsigned int
  4514.     height,
  4515.     i,
  4516.     magnify,
  4517.     scanline_pad,
  4518.     width;
  4519.  
  4520.   XColor
  4521.     color;
  4522.  
  4523.   XImage
  4524.     *ximage;
  4525.  
  4526.   /*
  4527.     Check boundry conditions.
  4528.   */
  4529.   magnify=1;
  4530.   for (i=1; i < resource_info->magnify; i++)
  4531.     magnify<<=1;
  4532.   while ((magnify*window->image.ximage->width) < window->magnify.width)
  4533.     magnify<<=1;
  4534.   while ((magnify*window->image.ximage->height) < window->magnify.height)
  4535.     magnify<<=1;
  4536.   while (magnify > window->magnify.width)
  4537.     magnify>>=1;
  4538.   while (magnify > window->magnify.height)
  4539.     magnify>>=1;
  4540.   if (magnify != previous_magnify)
  4541.     {
  4542.       unsigned int
  4543.         status;
  4544.  
  4545.       XTextProperty
  4546.         window_name;
  4547.  
  4548.       /*
  4549.         New magnify factor:  update magnify window name.
  4550.       */
  4551.       i=0;
  4552.       while ((1 << i) <= magnify)
  4553.         i++;
  4554.       (void) sprintf(window->magnify.name,"Magnify %uX",i);
  4555.       status=XStringListToTextProperty(&window->magnify.name,1,&window_name);
  4556.       if (status != 0)
  4557.         XSetWMName(display,window->magnify.id,&window_name);
  4558.     }
  4559.   previous_magnify=magnify;
  4560.   ximage=window->image.ximage;
  4561.   width=window->magnify.ximage->width;
  4562.   height=window->magnify.ximage->height;
  4563.   x=window->magnify.x-((width/magnify) >> 1);
  4564.   if (x < 0)
  4565.     x=0;
  4566.   else
  4567.     if (x > (ximage->width-(width/magnify)))
  4568.       x=ximage->width-width/magnify;
  4569.   y=window->magnify.y-((height/magnify) >> 1);
  4570.   if (y < 0)
  4571.     y=0;
  4572.   else
  4573.     if (y > (ximage->height-(height/magnify)))
  4574.       y=ximage->height-height/magnify;
  4575.   q=(unsigned char *) window->magnify.ximage->data;
  4576.   scanline_pad=window->magnify.ximage->bytes_per_line-
  4577.     ((width*window->magnify.ximage->bits_per_pixel) >> 3);
  4578.   if (ximage->bits_per_pixel < 8)
  4579.     {
  4580.       register unsigned char
  4581.         background,
  4582.         byte,
  4583.         foreground,
  4584.         p_bit,
  4585.         q_bit;
  4586.  
  4587.       register unsigned int
  4588.         plane;
  4589.  
  4590.       XPixelInfo
  4591.         *pixel_info;
  4592.  
  4593.       pixel_info=window->magnify.pixel_info;
  4594.       switch (ximage->bitmap_bit_order)
  4595.       {
  4596.         case LSBFirst:
  4597.         {
  4598.           /*
  4599.             Magnify little-endian bitmap.
  4600.           */
  4601.           background=0x00;
  4602.           foreground=0x80;
  4603.           if (ximage->format == XYBitmap)
  4604.             {
  4605.               background=(Intensity(pixel_info->foreground_color) <
  4606.                 Intensity(pixel_info->background_color) ? 0x80 : 0x00);
  4607.               foreground=(Intensity(pixel_info->background_color) <
  4608.                 Intensity(pixel_info->foreground_color) ? 0x80 : 0x00);
  4609.             }
  4610.           for (i=0; i < height; i+=magnify)
  4611.           {
  4612.             /*
  4613.               Propogate pixel magnify rows.
  4614.             */
  4615.             for (j=0; j < magnify; j++)
  4616.             {
  4617.               p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
  4618.                 ((x*ximage->bits_per_pixel) >> 3);
  4619.               p_bit=(x*ximage->bits_per_pixel) & 0x07;
  4620.               q_bit=0;
  4621.               byte=0;
  4622.               for (k=0; k < width; k+=magnify)
  4623.               {
  4624.                 /*
  4625.                   Propogate pixel magnify columns.
  4626.                 */
  4627.                 for (l=0; l < magnify; l++)
  4628.                 {
  4629.                   /*
  4630.                     Propogate each bit plane.
  4631.                   */
  4632.                   for (plane=0; plane < ximage->bits_per_pixel; plane++)
  4633.                   {
  4634.                     byte>>=1;
  4635.                     if (*p & (0x01 << (p_bit+plane)))
  4636.                       byte|=foreground;
  4637.                     else
  4638.                       byte|=background;
  4639.                     q_bit++;
  4640.                     if (q_bit == 8)
  4641.                       {
  4642.                         *q++=byte;
  4643.                         q_bit=0;
  4644.                         byte=0;
  4645.                       }
  4646.                   }
  4647.                 }
  4648.                 p_bit+=ximage->bits_per_pixel;
  4649.                 if (p_bit == 8)
  4650.                   {
  4651.                     p++;
  4652.                     p_bit=0;
  4653.                   }
  4654.                 if (q_bit != 0)
  4655.                   *q=byte >> (8-q_bit);
  4656.                 q+=scanline_pad;
  4657.               }
  4658.             }
  4659.             y++;
  4660.           }
  4661.           break;
  4662.         }
  4663.         case MSBFirst:
  4664.         default:
  4665.         {
  4666.           /*
  4667.             Magnify big-endian bitmap.
  4668.           */
  4669.           background=0x00;
  4670.           foreground=0x01;
  4671.           if (ximage->format == XYBitmap)
  4672.             {
  4673.               background=(Intensity(pixel_info->foreground_color) <
  4674.                 Intensity(pixel_info->background_color) ? 0x01 : 0x00);
  4675.               foreground=(Intensity(pixel_info->background_color) <
  4676.                 Intensity(pixel_info->foreground_color) ? 0x01 : 0x00);
  4677.             }
  4678.           for (i=0; i < height; i+=magnify)
  4679.           {
  4680.             /*
  4681.               Propogate pixel magnify rows.
  4682.             */
  4683.             for (j=0; j < magnify; j++)
  4684.             {
  4685.               p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
  4686.                 ((x*ximage->bits_per_pixel) >> 3);
  4687.               p_bit=(x*ximage->bits_per_pixel) & 0x07;
  4688.               q_bit=0;
  4689.               byte=0;
  4690.               for (k=0; k < width; k+=magnify)
  4691.               {
  4692.                 /*
  4693.                   Propogate pixel magnify columns.
  4694.                 */
  4695.                 for (l=0; l < magnify; l++)
  4696.                 {
  4697.                   /*
  4698.                     Propogate each bit plane.
  4699.                   */
  4700.                   for (plane=0; plane < ximage->bits_per_pixel; plane++)
  4701.                   {
  4702.                     byte<<=1;
  4703.                     if (*p & (0x80 >> (p_bit+plane)))
  4704.                       byte|=foreground;
  4705.                     else
  4706.                       byte|=background;
  4707.                     q_bit++;
  4708.                     if (q_bit == 8)
  4709.                       {
  4710.                         *q++=byte;
  4711.                         q_bit=0;
  4712.                         byte=0;
  4713.                       }
  4714.                   }
  4715.                 }
  4716.                 p_bit+=ximage->bits_per_pixel;
  4717.                 if (p_bit == 8)
  4718.                   {
  4719.                     p++;
  4720.                     p_bit=0;
  4721.                   }
  4722.                 if (q_bit != 0)
  4723.                   *q=byte << (8-q_bit);
  4724.                 q+=scanline_pad;
  4725.               }
  4726.             }
  4727.             y++;
  4728.           }
  4729.           break;
  4730.         }
  4731.       }
  4732.     }
  4733.   else
  4734.     switch (ximage->bits_per_pixel)
  4735.     {
  4736.       case 8:
  4737.       {
  4738.         /*
  4739.           Magnify 8 bit X image.
  4740.         */
  4741.         for (i=0; i < height; i+=magnify)
  4742.         {
  4743.           /*
  4744.             Propogate pixel magnify rows.
  4745.           */
  4746.           for (j=0; j < magnify; j++)
  4747.           {
  4748.             p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
  4749.               ((x*ximage->bits_per_pixel) >> 3);
  4750.             for (k=0; k < width; k+=magnify)
  4751.             {
  4752.               /*
  4753.                 Propogate pixel magnify columns.
  4754.               */
  4755.               for (l=0; l < magnify; l++)
  4756.                 *q++=(*p);
  4757.               p++;
  4758.             }
  4759.             q+=scanline_pad;
  4760.           }
  4761.           y++;
  4762.         }
  4763.         break;
  4764.       }
  4765.       default:
  4766.       {
  4767.         register unsigned int
  4768.           bytes_per_pixel,
  4769.           m;
  4770.  
  4771.         /*
  4772.           Magnify multi-byte X image.
  4773.         */
  4774.         bytes_per_pixel=ximage->bits_per_pixel >> 3;
  4775.         for (i=0; i < height; i+=magnify)
  4776.         {
  4777.           /*
  4778.             Propogate pixel magnify rows.
  4779.           */
  4780.           for (j=0; j < magnify; j++)
  4781.           {
  4782.             p=(unsigned char *) ximage->data+y*ximage->bytes_per_line+
  4783.               ((x*ximage->bits_per_pixel) >> 3);
  4784.             for (k=0; k < width; k+=magnify)
  4785.             {
  4786.               /*
  4787.                 Propogate pixel magnify columns.
  4788.               */
  4789.               for (l=0; l < magnify; l++)
  4790.                 for (m=0; m < bytes_per_pixel; m++)
  4791.                   *q++=(*(p+m));
  4792.               p+=bytes_per_pixel;
  4793.             }
  4794.             q+=scanline_pad;
  4795.           }
  4796.           y++;
  4797.         }
  4798.         break;
  4799.       }
  4800.     }
  4801.   /*
  4802.     Copy X image to magnify pixmap.
  4803.   */
  4804.   x=window->magnify.x-((width/magnify) >> 1);
  4805.   if (x < 0)
  4806.     x=(width >> 1)-window->magnify.x*magnify;
  4807.   else
  4808.     if (x > (ximage->width-(width/magnify)))
  4809.       x=(ximage->width-window->magnify.x)*magnify-(width >> 1);
  4810.     else
  4811.       x=0;
  4812.   y=window->magnify.y-((height/magnify) >> 1);
  4813.   if (y < 0)
  4814.     y=(height >> 1)-window->magnify.y*magnify;
  4815.   else
  4816.     if (y > (ximage->height-(height/magnify)))
  4817.       y=(ximage->height-window->magnify.y)*magnify-(height >> 1);
  4818.     else
  4819.       y=0;
  4820.   if ((x != 0) || (y != 0))
  4821.     XFillRectangle(display,window->magnify.pixmap,
  4822.       window->magnify.annotate_context,0,0,width,height);
  4823.   XPutImage(display,window->magnify.pixmap,window->magnify.annotate_context,
  4824.     window->magnify.ximage,0,0,x,y,width-x,height-y);
  4825.   if ((magnify > 1) && ((magnify <= (width >> 1)) &&
  4826.       (magnify <= (height >> 1))))
  4827.     {
  4828.       RectangleInfo
  4829.         highlight_info;
  4830.  
  4831.       /*
  4832.         Highlight center pixel.
  4833.       */
  4834.       highlight_info.x=window->magnify.width >> 1;
  4835.       highlight_info.y=window->magnify.height >> 1;
  4836.       highlight_info.width=magnify;
  4837.       highlight_info.height=magnify;
  4838.       XDrawRectangle(display,window->magnify.pixmap,
  4839.         window->magnify.highlight_context,highlight_info.x,highlight_info.y,
  4840.         highlight_info.width-1,highlight_info.height-1);
  4841.       XDrawRectangle(display,window->magnify.pixmap,
  4842.         window->magnify.annotate_context,highlight_info.x+1,highlight_info.y+1,
  4843.         highlight_info.width-3,highlight_info.height-3);
  4844.     }
  4845.   /*
  4846.     Show center pixel color.
  4847.   */
  4848.   color.pixel=
  4849.     XGetPixel(window->image.ximage,window->magnify.x,window->magnify.y);
  4850.   XQueryColor(display,window->image.map_info->colormap,&color);
  4851.   if (window->magnify.depth > 12)
  4852.     (void) sprintf(text,"%+d%+d  (%3u,%3u,%3u)",window->magnify.x,
  4853.       window->magnify.y,color.red >> 8,color.green >> 8,color.blue >> 8);
  4854.   else
  4855.     (void) sprintf(text,"%+d%+d  (%3u,%3u,%3u)  %lu ",window->magnify.x,
  4856.       window->magnify.y,color.red >> 8,color.green >> 8,color.blue >> 8,
  4857.       color.pixel);
  4858.   height=window->magnify.font_info->ascent+window->magnify.font_info->descent;
  4859.   x=(3*window->magnify.font_info->max_bounds.width) >> 2;
  4860.   y=window->magnify.font_info->ascent+(height >> 2);
  4861.   XDrawImageString(display,window->magnify.pixmap,
  4862.     window->magnify.annotate_context,x,y,text,strlen(text));
  4863.   /*
  4864.     Refresh magnify window.
  4865.   */
  4866.   magnify_window=window->magnify;
  4867.   magnify_window.x=0;
  4868.   magnify_window.y=0;
  4869.   XRefreshWindow(display,&magnify_window,(XEvent *) NULL);
  4870. }
  4871.  
  4872. /*
  4873. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4874. %                                                                             %
  4875. %                                                                             %
  4876. %                                                                             %
  4877. %   X M a k e P i x m a p                                                     %
  4878. %                                                                             %
  4879. %                                                                             %
  4880. %                                                                             %
  4881. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4882. %
  4883. %  Function XMakePixmap creates an X11 pixmap.
  4884. %
  4885. %  The format of the XMakePixmap routine is:
  4886. %
  4887. %      status=XMakePixmap(display,resource_info,window)
  4888. %
  4889. %  A description of each parameter follows:
  4890. %
  4891. %    o status: Function XMakePixmap returns True if the X pixmap is
  4892. %      successfully created.  False is returned is there is a memory shortage.
  4893. %
  4894. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  4895. %
  4896. %    o display: Specifies a connection to an X server; returned from
  4897. %      XOpenDisplay.
  4898. %
  4899. %    o window: Specifies a pointer to a XWindowInfo structure.
  4900. %
  4901. %
  4902. */
  4903. unsigned int XMakePixmap(display,resource_info,window)
  4904. Display
  4905.   *display;
  4906.  
  4907. XResourceInfo
  4908.   *resource_info;
  4909.  
  4910. XWindowInfo
  4911.   *window;
  4912. {
  4913.   if (window->ximage == (XImage *) NULL)
  4914.     return(False);
  4915.   /*
  4916.     Display busy cursor.
  4917.   */
  4918.   XDefineCursor(display,window->id,window->busy_cursor);
  4919.   XFlush(display);
  4920.   /*
  4921.     Create pixmap.
  4922.   */
  4923.   if (window->pixmap != (Pixmap) NULL)
  4924.     XFreePixmap(display,window->pixmap);
  4925.   window->pixmap=XCreatePixmap(display,window->id,(unsigned int)
  4926.     window->ximage->width,(unsigned int) window->ximage->height,window->depth);
  4927.   if (window->pixmap == (Pixmap) NULL)
  4928.     {
  4929.       /*
  4930.         Unable to allocate pixmap.
  4931.       */
  4932.       XDefineCursor(display,window->id,window->cursor);
  4933.       return(False);
  4934.     }
  4935.   /*
  4936.     Copy X image to pixmap.
  4937.   */
  4938.   XPutImage(display,window->pixmap,window->annotate_context,window->ximage,
  4939.     0,0,0,0,(unsigned int) window->ximage->width,
  4940.     (unsigned int) window->ximage->height);
  4941.   if (resource_info->debug)
  4942.     {
  4943.       (void) fprintf(stderr,"Pixmap:\n");
  4944.       (void) fprintf(stderr,"  width, height: %dx%d\n",window->ximage->width,
  4945.         window->ximage->height);
  4946.     }
  4947.   /*
  4948.     Restore cursor.
  4949.   */
  4950.   XDefineCursor(display,window->id,window->cursor);
  4951.   return(True);
  4952. }
  4953.  
  4954. /*
  4955. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4956. %                                                                             %
  4957. %                                                                             %
  4958. %                                                                             %
  4959. %   X M a k e S t a n d a r d C o l o r m a p                                 %
  4960. %                                                                             %
  4961. %                                                                             %
  4962. %                                                                             %
  4963. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4964. %
  4965. %  Function XMakeStandardColormap creates an X11 Standard Colormap.
  4966. %
  4967. %  The format of the XMakeStandardColormap routine is:
  4968. %
  4969. %      XMakeStandardColormap(display,visual_info,resource_info,image,
  4970. %        map_info,pixel_info)
  4971. %
  4972. %  A description of each parameter follows:
  4973. %
  4974. %    o display: Specifies a connection to an X server; returned from
  4975. %      XOpenDisplay.
  4976. %
  4977. %    o visual_info: Specifies a pointer to a X11 XVisualInfo structure;
  4978. %      returned from XGetVisualInfo.
  4979. %
  4980. %    o resource_info: Specifies a pointer to a X11 XResourceInfo structure.
  4981. %
  4982. %    o image: Specifies a pointer to a Image structure;  returned from
  4983. %      ReadImage.
  4984. %
  4985. %    o map_info: If a Standard Colormap type is specified, this structure is
  4986. %      initialized with info from the Standard Colormap.
  4987. %
  4988. %    o pixel_info: Specifies a pointer to a XPixelInfo structure.
  4989. %
  4990. %
  4991. */
  4992. static int IntensityCompare(x,y)
  4993. const void
  4994.   *x,
  4995.   *y;
  4996. {
  4997.   DiversityPacket
  4998.     *color_1,
  4999.     *color_2;
  5000.  
  5001.   color_1=(DiversityPacket *) x;
  5002.   color_2=(DiversityPacket *) y;
  5003.   return((int) Intensity(*color_2)-(int) Intensity(*color_1));
  5004. }
  5005.  
  5006. static int PopularityCompare(x,y)
  5007. const void
  5008.   *x,
  5009.   *y;
  5010. {
  5011.   DiversityPacket
  5012.     *color_1,
  5013.     *color_2;
  5014.  
  5015.   color_1=(DiversityPacket *) x;
  5016.   color_2=(DiversityPacket *) y;
  5017.   return((int) color_2->count-(int) color_1->count);
  5018. }
  5019.  
  5020. void XMakeStandardColormap(display,visual_info,resource_info,image,map_info,
  5021.   pixel_info)
  5022. Display
  5023.   *display;
  5024.  
  5025. XVisualInfo
  5026.   *visual_info;
  5027.  
  5028. XResourceInfo
  5029.   *resource_info;
  5030.  
  5031. Image
  5032.   *image;
  5033.  
  5034. XStandardColormap
  5035.   *map_info;
  5036.  
  5037. XPixelInfo
  5038.   *pixel_info;
  5039. {
  5040.   Colormap
  5041.     colormap;
  5042.  
  5043.   int
  5044.     status;
  5045.  
  5046.   register int
  5047.     i;
  5048.  
  5049.   unsigned int
  5050.     gray_value,
  5051.     number_colors,
  5052.     retain_colors;
  5053.  
  5054.   XColor
  5055.     color,
  5056.     *colors,
  5057.     *p;
  5058.  
  5059.   if (resource_info->map_type != (char *) NULL)
  5060.     {
  5061.       /*
  5062.         Standard Colormap is already defined (i.e. xstdcmap).
  5063.       */
  5064.       if (pixel_info->pixels != (unsigned long *) NULL)
  5065.         (void) free((char *) pixel_info->pixels);
  5066.       XGetPixelInfo(display,visual_info,map_info,resource_info,image,
  5067.         pixel_info);
  5068.       return;
  5069.     }
  5070.   if ((visual_info->class != DirectColor) && (visual_info->class != TrueColor))
  5071.     if ((image->class == DirectClass) ||
  5072.         (image->colors > visual_info->colormap_size))
  5073.       {
  5074.         /*
  5075.           Image has more colors than the visual supports.
  5076.         */
  5077.         QuantizeImage(image,(unsigned int) visual_info->colormap_size,
  5078.           resource_info->tree_depth,resource_info->dither,
  5079.           resource_info->colorspace,False);
  5080.         image->class=DirectClass;  /* promote to DirectClass */
  5081.       }
  5082.   /*
  5083.     Free previous and create new colormap.
  5084.   */
  5085.   XFreeStandardColormap(display,visual_info,map_info,pixel_info);
  5086.   colormap=XDefaultColormap(display,visual_info->screen);
  5087.   if (visual_info->visual != XDefaultVisual(display,visual_info->screen))
  5088.     colormap=XCreateColormap(display,XRootWindow(display,visual_info->screen),
  5089.       visual_info->visual,visual_info->class == DirectColor ?
  5090.       AllocAll : AllocNone);
  5091.   if (colormap == (Colormap) NULL)
  5092.     Error("Unable to create colormap",(char *) NULL);
  5093.   /*
  5094.     Initialize the map and pixel info structures.
  5095.   */
  5096.   XGetMapInfo(visual_info,colormap,map_info);
  5097.   XGetPixelInfo(display,visual_info,map_info,resource_info,image,pixel_info);
  5098.   /*
  5099.     Allocating colors in server colormap is based on visual class.
  5100.   */
  5101.   switch (visual_info->class)
  5102.   {
  5103.     case StaticGray:
  5104.     case StaticColor:
  5105.     {
  5106.       /*
  5107.         Define Standard Colormap for StaticGray or StaticColor visual.
  5108.       */
  5109.       number_colors=image->colors;
  5110.       colors=(XColor *) malloc(visual_info->colormap_size*sizeof(XColor));
  5111.       if (colors == (XColor *) NULL)
  5112.         Error("Unable to create colormap","Memory allocation failed");
  5113.       p=colors;
  5114.       color.flags=DoRed | DoGreen | DoBlue;
  5115.       if (visual_info->class == StaticColor)
  5116.         for (i=0; i < image->colors; i++)
  5117.         {
  5118.           color.red=(unsigned short) (image->colormap[i].red << 8);
  5119.           color.green=(unsigned short) (image->colormap[i].green << 8);
  5120.           color.blue=(unsigned short) (image->colormap[i].blue << 8);
  5121.           status=XAllocColor(display,colormap,&color);
  5122.           if (status == 0)
  5123.             {
  5124.               colormap=XCopyColormapAndFree(display,colormap);
  5125.               XAllocColor(display,colormap,&color);
  5126.             }
  5127.           pixel_info->pixels[i]=color.pixel;
  5128.           *p++=color;
  5129.         }
  5130.       else
  5131.         for (i=0; i < image->colors; i++)
  5132.         {
  5133.           gray_value=Intensity(image->colormap[i]);
  5134.           color.red=(unsigned short) (gray_value << 8);
  5135.           color.green=(unsigned short) (gray_value << 8);
  5136.           color.blue=(unsigned short) (gray_value << 8);
  5137.           status=XAllocColor(display,colormap,&color);
  5138.           if (status == 0)
  5139.             {
  5140.               colormap=XCopyColormapAndFree(display,colormap);
  5141.               XAllocColor(display,colormap,&color);
  5142.             }
  5143.           pixel_info->pixels[i]=color.pixel;
  5144.           *p++=color;
  5145.         }
  5146.       break;
  5147.     }
  5148.     case GrayScale:
  5149.     case PseudoColor:
  5150.     {
  5151.       unsigned int
  5152.         colormap_type;
  5153.  
  5154.       /*
  5155.         Define Standard Colormap for GrayScale or PseudoColor visual.
  5156.       */
  5157.       number_colors=image->colors;
  5158.       colors=(XColor *) malloc(visual_info->colormap_size*sizeof(XColor));
  5159.       if (colors == (XColor *) NULL)
  5160.         Error("Unable to create colormap","Memory allocation failed");
  5161.       /*
  5162.         Preallocate our GUI colors.
  5163.       */
  5164.       (void) XAllocColor(display,colormap,&pixel_info->foreground_color);
  5165.       (void) XAllocColor(display,colormap,&pixel_info->background_color);
  5166.       (void) XAllocColor(display,colormap,&pixel_info->border_color);
  5167.       (void) XAllocColor(display,colormap,&pixel_info->matte_color);
  5168.       (void) XAllocColor(display,colormap,&pixel_info->highlight_color);
  5169.       (void) XAllocColor(display,colormap,&pixel_info->shadow_color);
  5170.       (void) XAllocColor(display,colormap,&pixel_info->depth_color);
  5171.       (void) XAllocColor(display,colormap,&pixel_info->trough_color);
  5172.       for (i=0; i < MaxNumberPens; i++)
  5173.         (void) XAllocColor(display,colormap,&pixel_info->pen_color[i]);
  5174.       /*
  5175.         Determine if image colors will "fit" into X server colormap.
  5176.       */
  5177.       colormap_type=resource_info->colormap;
  5178.       status=XAllocColorCells(display,colormap,False,(unsigned long *) NULL,0,
  5179.         pixel_info->pixels,image->colors);
  5180.       if (status != 0)
  5181.         colormap_type=PrivateColormap;
  5182.       if (colormap_type == SharedColormap)
  5183.         {
  5184.           DiversityPacket
  5185.             *diversity;
  5186.  
  5187.           register RunlengthPacket
  5188.             *q;
  5189.  
  5190.           unsigned short
  5191.             index;
  5192.  
  5193.           /*
  5194.             Define Standard colormap for shared GrayScale or PseudoColor visual:
  5195.           */
  5196.           diversity=(DiversityPacket *)
  5197.             malloc(image->colors*sizeof(DiversityPacket));
  5198.           if (diversity == (DiversityPacket *) NULL)
  5199.             Error("Unable to create colormap","Memory allocation failed");
  5200.           for (i=0; i < image->colors; i++)
  5201.           {
  5202.             diversity[i].red=image->colormap[i].red;
  5203.             diversity[i].green=image->colormap[i].green;
  5204.             diversity[i].blue=image->colormap[i].blue;
  5205.             diversity[i].index=(unsigned short) i;
  5206.             diversity[i].count=0;
  5207.           }
  5208.           q=image->pixels;
  5209.           for (i=0; i < image->packets; i++)
  5210.           {
  5211.             diversity[q->index].count+=(q->length+1);
  5212.             q++;
  5213.           }
  5214.           /*
  5215.             Sort colors by decreasing intensity.
  5216.           */
  5217.           (void) qsort((void *) diversity,image->colors,sizeof(DiversityPacket),
  5218.             IntensityCompare);
  5219.           for (i=0; i < image->colors; i+=Max(image->colors >> 4,2))
  5220.             diversity[i].count<<=4;  /* increase this colors popularity */
  5221.           diversity[image->colors-1].count<<=4;
  5222.           (void) qsort((void *) diversity,image->colors,sizeof(DiversityPacket),
  5223.             PopularityCompare);
  5224.           /*
  5225.             Allocate colors.
  5226.           */
  5227.           p=colors;
  5228.           color.flags=DoRed | DoGreen | DoBlue;
  5229.           if (visual_info->class == PseudoColor)
  5230.             for (i=0; i < image->colors; i++)
  5231.             {
  5232.               index=diversity[i].index;
  5233.               color.red=(unsigned short) (image->colormap[index].red << 8);
  5234.               color.green=(unsigned short) (image->colormap[index].green << 8);
  5235.               color.blue=(unsigned short) (image->colormap[index].blue << 8);
  5236.               status=XAllocColor(display,colormap,&color);
  5237.               if (status == 0)
  5238.                 break;
  5239.               pixel_info->pixels[index]=color.pixel;
  5240.               *p++=color;
  5241.             }
  5242.           else
  5243.             for (i=0; i < image->colors; i++)
  5244.             {
  5245.               index=diversity[i].index;
  5246.               gray_value=Intensity(image->colormap[index]);
  5247.               color.red=(unsigned short) (gray_value << 8);
  5248.               color.green=(unsigned short) (gray_value << 8);
  5249.               color.blue=(unsigned short) (gray_value << 8);
  5250.               status=XAllocColor(display,colormap,&color);
  5251.               if (status == 0)
  5252.                 break;
  5253.               pixel_info->pixels[index]=color.pixel;
  5254.               *p++=color;
  5255.             }
  5256.           if (i < image->colors)
  5257.             {
  5258.               register int
  5259.                 j;
  5260.  
  5261.               XColor
  5262.                 *server_colors;
  5263.  
  5264.               /*
  5265.                 Read X server colormap.
  5266.               */
  5267.               server_colors=(XColor *)
  5268.                 malloc(visual_info->colormap_size*sizeof(XColor));
  5269.               if (server_colors == (XColor *) NULL)
  5270.                 Error("Unable to create colormap","Memory allocation failed");
  5271.               for (j=0; j < visual_info->colormap_size; j++)
  5272.                 server_colors[j].pixel=(unsigned long) j;
  5273.               XQueryColors(display,colormap,server_colors,
  5274.                 (int) Min(visual_info->colormap_size,256));
  5275.               /*
  5276.                 Select remaining colors from X server colormap.
  5277.               */
  5278.               if (visual_info->class == PseudoColor)
  5279.                 for (; i < image->colors; i++)
  5280.                 {
  5281.                   index=diversity[i].index;
  5282.                   color.red=(unsigned short) (image->colormap[index].red << 8);
  5283.                   color.green=(unsigned short)
  5284.                     (image->colormap[index].green << 8);
  5285.                   color.blue=(unsigned short)
  5286.                     (image->colormap[index].blue << 8);
  5287.                   XBestPixel(display,colormap,server_colors,
  5288.                     (unsigned int) visual_info->colormap_size,&color);
  5289.                   pixel_info->pixels[index]=color.pixel;
  5290.                   *p++=color;
  5291.                 }
  5292.               else
  5293.                 for (; i < image->colors; i++)
  5294.                 {
  5295.                   index=diversity[i].index;
  5296.                   gray_value=Intensity(image->colormap[index]);
  5297.                   color.red=(unsigned short) (gray_value << 8);
  5298.                   color.green=(unsigned short) (gray_value << 8);
  5299.                   color.blue=(unsigned short) (gray_value << 8);
  5300.                   XBestPixel(display,colormap,server_colors,
  5301.                     (unsigned int) visual_info->colormap_size,&color);
  5302.                   pixel_info->pixels[index]=color.pixel;
  5303.                   *p++=color;
  5304.                 }
  5305.               if (image->colors < visual_info->colormap_size)
  5306.                 {
  5307.                   /*
  5308.                     Fill up colors array-- more choices for pen colors.
  5309.                   */
  5310.                   retain_colors=
  5311.                     Min(visual_info->colormap_size-image->colors,256);
  5312.                   for (i=0; i < retain_colors; i++)
  5313.                     *p++=server_colors[i];
  5314.                   number_colors+=retain_colors;
  5315.                 }
  5316.               (void) free((char *) server_colors);
  5317.             }
  5318.           (void) free((char *) diversity);
  5319.           break;
  5320.         }
  5321.       /*
  5322.         Define Standard colormap for private GrayScale or PseudoColor visual.
  5323.       */
  5324.       if (status == 0)
  5325.         {
  5326.           /*
  5327.             Not enough colormap entries in the colormap-- Create a new colormap.
  5328.           */
  5329.           colormap=XCreateColormap(display,
  5330.             XRootWindow(display,visual_info->screen),visual_info->visual,
  5331.             AllocNone);
  5332.           if (colormap == (Colormap) NULL)
  5333.             Error("Unable to create colormap",(char *) NULL);
  5334.           map_info->colormap=colormap;
  5335.           if (image->colors < visual_info->colormap_size)
  5336.             {
  5337.               /*
  5338.                 Retain colors from the default colormap to help lessens the
  5339.                 effects of colormap flashing.
  5340.               */
  5341.               retain_colors=Min(visual_info->colormap_size-image->colors,256);
  5342.               p=colors+image->colors;
  5343.               for (i=0; i < retain_colors; i++)
  5344.               {
  5345.                 p->pixel=(unsigned long) i;
  5346.                 p++;
  5347.               }
  5348.               XQueryColors(display,
  5349.                 XDefaultColormap(display,visual_info->screen),
  5350.                 colors+image->colors,(int) retain_colors);
  5351.               /*
  5352.                 Transfer colors from default to private colormap.
  5353.               */
  5354.               XAllocColorCells(display,colormap,False,(unsigned long *) NULL,0,
  5355.                 pixel_info->pixels,retain_colors);
  5356.               p=colors+image->colors;
  5357.               for (i=0; i < retain_colors; i++)
  5358.               {
  5359.                 p->pixel=pixel_info->pixels[i];
  5360.                 p++;
  5361.               }
  5362.               XStoreColors(display,colormap,colors+image->colors,retain_colors);
  5363.               number_colors+=retain_colors;
  5364.             }
  5365.           XAllocColorCells(display,colormap,False,(unsigned long *) NULL,0,
  5366.             pixel_info->pixels,image->colors);
  5367.         }
  5368.       /*
  5369.         Store the image colormap.
  5370.       */
  5371.       p=colors;
  5372.       color.flags=DoRed | DoGreen | DoBlue;
  5373.       if (visual_info->class == PseudoColor)
  5374.         for (i=0; i < image->colors; i++)
  5375.         {
  5376.           color.red=(unsigned short) (image->colormap[i].red << 8);
  5377.           color.green=(unsigned short) (image->colormap[i].green << 8);
  5378.           color.blue=(unsigned short) (image->colormap[i].blue << 8);
  5379.           color.pixel=pixel_info->pixels[i];
  5380.           *p++=color;
  5381.         }
  5382.       else
  5383.         for (i=0; i < image->colors; i++)
  5384.         {
  5385.           gray_value=Intensity(image->colormap[i]);
  5386.           color.red=(unsigned short) (gray_value << 8);
  5387.           color.green=(unsigned short) (gray_value << 8);
  5388.           color.blue=(unsigned short) (gray_value << 8);
  5389.           color.pixel=pixel_info->pixels[i];
  5390.           *p++=color;
  5391.         }
  5392.       XStoreColors(display,colormap,colors,image->colors);
  5393.       break;
  5394.     }
  5395.     case TrueColor:
  5396.     case DirectColor:
  5397.     default:
  5398.     {
  5399.       unsigned int
  5400.         linear_colormap;
  5401.  
  5402.       /*
  5403.         Define Standard Colormap for TrueColor or DirectColor visual.
  5404.       */
  5405.       number_colors=(unsigned int) ((map_info->red_max*map_info->red_mult)+
  5406.         (map_info->green_max*map_info->green_mult)+
  5407.         (map_info->blue_max*map_info->blue_mult)+1);
  5408.       linear_colormap=
  5409.         ((map_info->red_max+1) == visual_info->colormap_size) &&
  5410.         ((map_info->green_max+1) == visual_info->colormap_size) &&
  5411.         ((map_info->blue_max+1) == visual_info->colormap_size);
  5412.       if (linear_colormap)
  5413.         number_colors=visual_info->colormap_size;
  5414.       /*
  5415.         Allocate color array.
  5416.       */
  5417.       colors=(XColor *) malloc(number_colors*sizeof(XColor));
  5418.       if (colors == (XColor *) NULL)
  5419.         Error("Unable to create colormap","Memory allocation failed");
  5420.       /*
  5421.         Initialize linear color ramp.
  5422.       */
  5423.       p=colors;
  5424.       color.flags=DoRed | DoGreen | DoBlue;
  5425.       if (linear_colormap)
  5426.         for (i=0; i < number_colors; i++)
  5427.         {
  5428.           color.blue=(unsigned short) 0;
  5429.           if (map_info->blue_max > 0)
  5430.             color.blue=(unsigned short)
  5431.               (((i % map_info->green_mult)*65535)/map_info->blue_max);
  5432.           color.green=color.blue;
  5433.           color.red=color.blue;
  5434.           color.pixel=XStandardPixel(map_info,color,16);
  5435.           *p++=color;
  5436.         }
  5437.       else
  5438.         for (i=0; i < number_colors; i++)
  5439.         {
  5440.           color.red=(unsigned short) 0;
  5441.           if (map_info->red_max > 0)
  5442.             color.red=(unsigned short)
  5443.               (((i/map_info->red_mult)*65535)/map_info->red_max);
  5444.           color.green=(unsigned short) 0;
  5445.           if (map_info->green_max > 0)
  5446.             color.green=(unsigned short) ((((i/map_info->green_mult) %
  5447.               (map_info->green_max+1))*65535)/map_info->green_max);
  5448.           color.blue=(unsigned short) 0;
  5449.           if (map_info->blue_max > 0)
  5450.             color.blue=(unsigned short)
  5451.               (((i % map_info->green_mult)*65535)/map_info->blue_max);
  5452.           color.pixel=XStandardPixel(map_info,color,16);
  5453.           *p++=color;
  5454.         }
  5455.       if ((visual_info->class == DirectColor) &&
  5456.           (colormap != XDefaultColormap(display,visual_info->screen)))
  5457.         XStoreColors(display,colormap,colors,number_colors);
  5458.       else
  5459.         for (i=0; i < number_colors; i++)
  5460.           XAllocColor(display,colormap,&colors[i]);
  5461.       break;
  5462.     }
  5463.   }
  5464.   if ((visual_info->class != DirectColor) && (visual_info->class != TrueColor))
  5465.     {
  5466.       /*
  5467.         Set foreground, background, border, etc. pixels.
  5468.       */
  5469.       XBestPixel(display,colormap,colors,number_colors,
  5470.         &pixel_info->foreground_color);
  5471.       XBestPixel(display,colormap,colors,number_colors,
  5472.         &pixel_info->background_color);
  5473.       if (pixel_info->background_color.pixel ==
  5474.           pixel_info->foreground_color.pixel)
  5475.         {
  5476.           /*
  5477.             Foreground and background colors must differ.
  5478.           */
  5479.           pixel_info->background_color.red=(~pixel_info->foreground_color.red);
  5480.           pixel_info->background_color.green=
  5481.             (~pixel_info->foreground_color.green);
  5482.           pixel_info->background_color.blue=
  5483.             (~pixel_info->foreground_color.blue);
  5484.           XBestPixel(display,colormap,colors,number_colors,
  5485.             &pixel_info->background_color);
  5486.         }
  5487.       XBestPixel(display,colormap,colors,number_colors,
  5488.         &pixel_info->border_color);
  5489.       XBestPixel(display,colormap,colors,number_colors,
  5490.         &pixel_info->matte_color);
  5491.       XBestPixel(display,colormap,colors,number_colors,
  5492.         &pixel_info->highlight_color);
  5493.       XBestPixel(display,colormap,colors,number_colors,
  5494.         &pixel_info->shadow_color);
  5495.       XBestPixel(display,colormap,colors,number_colors,
  5496.         &pixel_info->depth_color);
  5497.       XBestPixel(display,colormap,colors,number_colors,
  5498.         &pixel_info->trough_color);
  5499.       for (i=0; i < MaxNumberPens; i++)
  5500.       {
  5501.         XBestPixel(display,colormap,colors,number_colors,
  5502.           &pixel_info->pen_color[i]);
  5503.         pixel_info->pixels[image->colors+i]=pixel_info->pen_color[i].pixel;
  5504.       }
  5505.       pixel_info->colors=image->colors+MaxNumberPens;
  5506.     }
  5507.   (void) free((char *) colors);
  5508.   if (resource_info->debug)
  5509.     {
  5510.       (void) fprintf(stderr,"Standard Colormap:\n");
  5511.       (void) fprintf(stderr,"  colormap id: 0x%lx\n",map_info->colormap);
  5512.       (void) fprintf(stderr,"  red, green, blue max: %lu %lu %lu\n",
  5513.         map_info->red_max,map_info->green_max,map_info->blue_max);
  5514.       (void) fprintf(stderr,"  red, green, blue mult: %lu %lu %lu\n",
  5515.         map_info->red_mult,map_info->green_mult,map_info->blue_mult);
  5516.     }
  5517. }
  5518.  
  5519. /*
  5520. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5521. %                                                                             %
  5522. %                                                                             %
  5523. %                                                                             %
  5524. %   X M a k e W i n d o w                                                     %
  5525. %                                                                             %
  5526. %                                                                             %
  5527. %                                                                             %
  5528. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5529. %
  5530. %  Function XMakeWindow creates an X11 window.
  5531. %
  5532. %  The format of the XMakeWindow routine is:
  5533. %
  5534. %      XMakeWindow(display,parent,argv,argc,class_hint,manager_hints,property,
  5535. %        window_info)
  5536. %
  5537. %  A description of each parameter follows:
  5538. %
  5539. %    o display: Specifies a connection to an X server; returned from
  5540. %      XOpenDisplay.
  5541. %
  5542. %    o parent: Specifies the parent window_info.
  5543. %
  5544. %    o argv: Specifies the application's argument list.
  5545. %
  5546. %    o argc: Specifies the number of arguments.
  5547. %
  5548. %    o class_hint: Specifies a pointer to a X11 XClassHint structure.
  5549. %
  5550. %    o manager_hints: Specifies a pointer to a X11 XWMHints structure.
  5551. %
  5552. %    o property: A property to define on the window_info.
  5553. %
  5554. %    o window_info: Specifies a pointer to a X11 XWindowInfo structure.
  5555. %
  5556. %
  5557. */
  5558. void XMakeWindow(display,parent,argv,argc,class_hint,manager_hints,property,
  5559.   window_info)
  5560. Display
  5561.   *display;
  5562.  
  5563. Window
  5564.   parent;
  5565.  
  5566. char
  5567.   **argv;
  5568.  
  5569. int
  5570.   argc;
  5571.  
  5572. XClassHint
  5573.   *class_hint;
  5574.  
  5575. XWMHints
  5576.   *manager_hints;
  5577.  
  5578. Atom
  5579.   property;
  5580.  
  5581. XWindowInfo
  5582.   *window_info;
  5583. {
  5584. #define MinWindowSize  64
  5585.  
  5586.   int
  5587.     status;
  5588.  
  5589.   XSizeHints
  5590.     *size_hints;
  5591.  
  5592.   XTextProperty
  5593.     icon_name,
  5594.     window_name;
  5595.  
  5596.   /*
  5597.     Set window_info hints.
  5598.   */
  5599.   size_hints=XAllocSizeHints();
  5600.   if (size_hints == (XSizeHints *) NULL)
  5601.     Error("Unable to make X window","Memory allocation failed");
  5602.   size_hints->flags=window_info->flags;
  5603.   size_hints->x=window_info->x;
  5604.   size_hints->y=window_info->y;
  5605.   size_hints->width=window_info->width;
  5606.   size_hints->height=window_info->height;
  5607.   if (!window_info->immutable)
  5608.     {
  5609.       /*
  5610.         Window size can be changed.
  5611.       */
  5612.       size_hints->min_width=window_info->min_width;
  5613.       size_hints->min_height=window_info->min_height;
  5614.       size_hints->flags|=PMinSize;
  5615.     }
  5616.   else
  5617.     {
  5618.       /*
  5619.         Window size cannot be changed.
  5620.       */
  5621.       size_hints->min_width=window_info->width;
  5622.       size_hints->min_height=window_info->height;
  5623.       size_hints->max_width=window_info->width;
  5624.       size_hints->max_height=window_info->height;
  5625.       size_hints->flags|=PMinSize | PMaxSize;
  5626.     }
  5627.   size_hints->flags|=PResizeInc;
  5628.   size_hints->width_inc=window_info->width_inc;
  5629.   size_hints->height_inc=window_info->height_inc;
  5630. #ifndef PRE_R4_ICCCM
  5631.   size_hints->flags|=PBaseSize;
  5632.   size_hints->base_width=size_hints->width_inc;
  5633.   size_hints->base_height=size_hints->height_inc;
  5634. #endif
  5635.   if (window_info->geometry != (char *) NULL)
  5636.     {
  5637.       char
  5638.         default_geometry[MaxTextLength],
  5639.         geometry[MaxTextLength];
  5640.  
  5641.       int
  5642.         flags,
  5643.         gravity;
  5644.  
  5645.       register char
  5646.         *p;
  5647.  
  5648.       /*
  5649.         User specified geometry.
  5650.       */
  5651.       (void) sprintf(default_geometry,"%dx%d",size_hints->width,
  5652.         size_hints->height);
  5653.       (void) strcpy(geometry,window_info->geometry);
  5654.       p=geometry;
  5655.       while ((int) strlen(p) > 0)
  5656.       {
  5657.         if (!isspace(*p) && (*p != '%'))
  5658.           p++;
  5659.         else
  5660.           (void) strcpy(p,p+1);
  5661.       }
  5662.       flags=XWMGeometry(display,window_info->screen,geometry,default_geometry,
  5663.         window_info->border_width,size_hints,&size_hints->x,&size_hints->y,
  5664.         &size_hints->width,&size_hints->height,&gravity);
  5665.       if ((flags & WidthValue) && (flags & HeightValue))
  5666.         size_hints->flags|=USSize;
  5667.       if ((flags & XValue) && (flags & YValue))
  5668.         {
  5669.           size_hints->flags|=USPosition;
  5670.           window_info->x=size_hints->x;
  5671.           window_info->y=size_hints->y;
  5672.         }
  5673. #ifndef PRE_R4_ICCCM
  5674.       size_hints->win_gravity=gravity;
  5675.       size_hints->flags|=PWinGravity;
  5676. #endif
  5677.     }
  5678.   if (window_info->id == (Window) NULL)
  5679.     window_info->id=XCreateWindow(display,parent,window_info->x,window_info->y,
  5680.       window_info->width,window_info->height,window_info->border_width,
  5681.       window_info->depth,InputOutput,window_info->visual,window_info->mask,
  5682.       &window_info->attributes);
  5683.   else
  5684.     {
  5685.       unsigned int
  5686.         mask;
  5687.  
  5688.       XEvent
  5689.         sans_event;
  5690.  
  5691.       XWindowChanges
  5692.         window_changes;
  5693.  
  5694.       /*
  5695.         Window already exists;  change relevant attributes.
  5696.       */
  5697.       XChangeWindowAttributes(display,window_info->id,window_info->mask,
  5698.         &window_info->attributes);
  5699.       mask=ConfigureNotify;
  5700.       while (XCheckTypedWindowEvent(display,window_info->id,mask,&sans_event));
  5701.       window_changes.x=window_info->x;
  5702.       window_changes.y=window_info->y;
  5703.       window_changes.width=window_info->width;
  5704.       window_changes.height=window_info->height;
  5705.       mask=CWWidth | CWHeight;
  5706.       if (window_info->flags & USPosition)
  5707.         mask|=CWX | CWY;
  5708.       XReconfigureWMWindow(display,window_info->id,window_info->screen,mask,
  5709.         &window_changes);
  5710.     }
  5711.   if (window_info->id == (Window) NULL)
  5712.     Error("Unable to create window",window_info->name);
  5713.   status=XStringListToTextProperty(&window_info->name,1,&window_name);
  5714.   if (status == 0)
  5715.     Error("Unable to create text property",window_info->name);
  5716.   status=XStringListToTextProperty(&window_info->icon_name,1,&icon_name);
  5717.   if (status == 0)
  5718.     Error("Unable to create text property",window_info->icon_name);
  5719.   if (window_info->icon_geometry != (char *) NULL)
  5720.     {
  5721.       int
  5722.         flags,
  5723.         gravity,
  5724.         height,
  5725.         width;
  5726.  
  5727.       /*
  5728.         User specified icon geometry.
  5729.       */
  5730.       size_hints->flags|=USPosition;
  5731.       flags=XWMGeometry(display,window_info->screen,window_info->icon_geometry,
  5732.         (char *) NULL,0,size_hints,&manager_hints->icon_x,
  5733.         &manager_hints->icon_y,&width,&height,&gravity);
  5734.       if ((flags & XValue) && (flags & YValue))
  5735.         manager_hints->flags|=IconPositionHint;
  5736.     }
  5737.   XSetWMProperties(display,window_info->id,&window_name,&icon_name,argv,argc,
  5738.     size_hints,manager_hints,class_hint);
  5739.   if (property != (Atom) NULL)
  5740.     XSetWMProtocols(display,window_info->id,&property,1);
  5741.   XFree((void *) size_hints);
  5742. }
  5743.  
  5744. /*
  5745. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5746. %                                                                             %
  5747. %                                                                             %
  5748. %                                                                             %
  5749. %   X R e f r e s h W i n d o w                                               %
  5750. %                                                                             %
  5751. %                                                                             %
  5752. %                                                                             %
  5753. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5754. %
  5755. %  Function XRefreshWindow refreshes an image in a X window.
  5756. %
  5757. %  The format of the XRefreshWindow routine is:
  5758. %
  5759. %      XRefreshWindow(display,window,event)
  5760. %
  5761. %  A description of each parameter follows:
  5762. %
  5763. %    o display: Specifies a connection to an X server;  returned from
  5764. %      XOpenDisplay.
  5765. %
  5766. %    o window: Specifies a pointer to a XWindowInfo structure.
  5767. %
  5768. %    o event: Specifies a pointer to a XEvent structure.  If it is NULL,
  5769. %      the entire image is refreshed.
  5770. %
  5771. %
  5772. */
  5773. void XRefreshWindow(display,window,event)
  5774. Display
  5775.   *display;
  5776.  
  5777. XWindowInfo
  5778.   *window;
  5779.  
  5780. XEvent
  5781.   *event;
  5782. {
  5783.   int
  5784.     x,
  5785.     y;
  5786.  
  5787.   unsigned int
  5788.     height,
  5789.     width;
  5790.  
  5791.   if (event != (XEvent *) NULL)
  5792.     {
  5793.       /*
  5794.         Determine geometry from expose event.
  5795.       */
  5796.       x=event->xexpose.x;
  5797.       y=event->xexpose.y;
  5798.       width=event->xexpose.width;
  5799.       height=event->xexpose.height;
  5800.     }
  5801.   else
  5802.     {
  5803.       XEvent
  5804.         sans_event;
  5805.  
  5806.       /*
  5807.         Refresh entire window; discard outstanding expose events.
  5808.       */
  5809.       x=0;
  5810.       y=0;
  5811.       width=window->width;
  5812.       height=window->height;
  5813.       while (XCheckTypedWindowEvent(display,window->id,Expose,&sans_event));
  5814.     }
  5815.   /*
  5816.     Check boundary conditions.
  5817.   */
  5818.   if ((window->ximage->width-(x+window->x)) < width)
  5819.     width=window->ximage->width-(x+window->x);
  5820.   if ((window->ximage->height-(y+window->y)) < height)
  5821.     height=window->ximage->height-(y+window->y);
  5822.   /*
  5823.     Refresh image.
  5824.   */
  5825.   if (window->pixmap != (Pixmap) NULL)
  5826.     {
  5827.       if (window->depth > 1)
  5828.         XCopyArea(display,window->pixmap,window->id,window->annotate_context,
  5829.           x+window->x,y+window->y,width,height,x,y);
  5830.       else
  5831.         XCopyPlane(display,window->pixmap,window->id,window->highlight_context,
  5832.           x+window->x,y+window->y,width,height,x,y,1L);
  5833.     }
  5834.   else
  5835.     XPutImage(display,window->id,window->annotate_context,window->ximage,
  5836.       x+window->x,y+window->y,x,y,width,height);
  5837. }
  5838.  
  5839. /*
  5840. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5841. %                                                                             %
  5842. %                                                                             %
  5843. %                                                                             %
  5844. %   X S e l e c t W i n d o w                                                 %
  5845. %                                                                             %
  5846. %                                                                             %
  5847. %                                                                             %
  5848. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5849. %
  5850. %  Function XSelectWindow allows a user to select a window using the mouse.  If
  5851. %  the mouse moves, a clipping rectangle is drawn and the extents of the
  5852. %  rectangle is returned in the clip_info structure.
  5853. %
  5854. %  The format of the XSelectWindow function is:
  5855. %
  5856. %      target_window=XSelectWindow(display,clip_info)
  5857. %
  5858. %  A description of each parameter follows:
  5859. %
  5860. %    o window: XSelectWindow returns the window id.
  5861. %
  5862. %    o display: Specifies a pointer to the Display structure;  returned from
  5863. %      XOpenDisplay.
  5864. %
  5865. %    o clip_info: Specifies a pointer to a RectangleInfo structure.  It
  5866. %      contains the extents of any clipping rectangle.
  5867. %
  5868. %
  5869. */
  5870. Window XSelectWindow(display,clip_info)
  5871. Display
  5872.   *display;
  5873.  
  5874. RectangleInfo
  5875.   *clip_info;
  5876. {
  5877. #define MinimumClipArea  (unsigned int) 9
  5878.  
  5879.   Cursor
  5880.     target_cursor;
  5881.  
  5882.   GC
  5883.     annotate_context;
  5884.  
  5885.   int
  5886.     presses,
  5887.     status,
  5888.     x_offset,
  5889.     y_offset;
  5890.  
  5891.   Window
  5892.     root_window,
  5893.     target_window;
  5894.  
  5895.   XEvent
  5896.     event;
  5897.  
  5898.   XGCValues
  5899.     context_values;
  5900.  
  5901.   /*
  5902.     Initialize graphic context.
  5903.   */
  5904.   root_window=XRootWindow(display,XDefaultScreen(display));
  5905.   context_values.background=XBlackPixel(display,XDefaultScreen(display));
  5906.   context_values.foreground=XWhitePixel(display,XDefaultScreen(display));
  5907.   context_values.function=GXinvert;
  5908.   context_values.plane_mask=
  5909.     context_values.background ^ context_values.foreground;
  5910.   context_values.subwindow_mode=IncludeInferiors;
  5911.   annotate_context=XCreateGC(display,root_window,GCBackground | GCForeground |
  5912.     GCFunction | GCPlaneMask | GCSubwindowMode,&context_values);
  5913.   if (annotate_context == (GC) NULL)
  5914.     return(False);
  5915.   /*
  5916.     Grab the pointer using target cursor.
  5917.   */
  5918.   target_cursor=XMakeCursor(display,root_window,
  5919.     XDefaultColormap(display,XDefaultScreen(display)),"white","black");
  5920.   status=XGrabPointer(display,root_window,False,(unsigned int)
  5921.     (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask),GrabModeSync,
  5922.     GrabModeAsync,root_window,target_cursor,CurrentTime);
  5923.   if (status != GrabSuccess)
  5924.     Error("Unable to grab the mouse",(char *) NULL);
  5925.   /*
  5926.     Select a window.
  5927.   */
  5928.   clip_info->width=0;
  5929.   clip_info->height=0;
  5930.   presses=0;
  5931.   target_window=(Window) NULL;
  5932.   x_offset=0;
  5933.   y_offset=0;
  5934.   do
  5935.   {
  5936.     if ((clip_info->width*clip_info->height) >= MinimumClipArea)
  5937.       XDrawRectangle(display,root_window,annotate_context,clip_info->x,
  5938.         clip_info->y,clip_info->width-1,clip_info->height-1);
  5939.     /*
  5940.       Allow another event.
  5941.     */
  5942.     XAllowEvents(display,SyncPointer,CurrentTime);
  5943.     XWindowEvent(display,root_window,ButtonPressMask | ButtonReleaseMask |
  5944.       ButtonMotionMask,&event);
  5945.     if ((clip_info->width*clip_info->height) >= MinimumClipArea)
  5946.       XDrawRectangle(display,root_window,annotate_context,clip_info->x,
  5947.         clip_info->y,clip_info->width-1,clip_info->height-1);
  5948.     switch (event.type)
  5949.     {
  5950.       case ButtonPress:
  5951.       {
  5952.         if (target_window == (Window) NULL)
  5953.           {
  5954.             target_window=event.xbutton.subwindow;
  5955.             if (target_window == (Window) NULL)
  5956.               target_window=root_window;
  5957.           }
  5958.         x_offset=event.xbutton.x_root;
  5959.         y_offset=event.xbutton.y_root;
  5960.         clip_info->x=x_offset;
  5961.         clip_info->y=y_offset;
  5962.         clip_info->width=0;
  5963.         clip_info->height=0;
  5964.         presses++;
  5965.         break;
  5966.       }
  5967.       case ButtonRelease:
  5968.       {
  5969.         presses--;
  5970.         break;
  5971.       }
  5972.       case MotionNotify:
  5973.       {
  5974.         /*
  5975.           Discard pending button motion events.
  5976.         */
  5977.         while (XCheckMaskEvent(display,ButtonMotionMask,&event));
  5978.         clip_info->x=event.xmotion.x;
  5979.         clip_info->y=event.xmotion.y;
  5980.         /*
  5981.           Check boundary conditions.
  5982.         */
  5983.         if (clip_info->x < x_offset)
  5984.           clip_info->width=(unsigned int) (x_offset-clip_info->x);
  5985.         else
  5986.           {
  5987.             clip_info->width=(unsigned int) (clip_info->x-x_offset);
  5988.             clip_info->x=x_offset;
  5989.           }
  5990.         if (clip_info->y < y_offset)
  5991.           clip_info->height=(unsigned int) (y_offset-clip_info->y);
  5992.         else
  5993.           {
  5994.             clip_info->height=(unsigned int) (clip_info->y-y_offset);
  5995.             clip_info->y=y_offset;
  5996.           }
  5997.       }
  5998.       default:
  5999.         break;
  6000.     }
  6001.   }
  6002.   while ((target_window == (Window) NULL) || (presses > 0));
  6003.   XUngrabPointer(display,CurrentTime);
  6004.   XFreeCursor(display,target_cursor);
  6005.   XFreeGC(display,annotate_context);
  6006.   if ((clip_info->width*clip_info->height) < MinimumClipArea)
  6007.     {
  6008.       clip_info->width=0;
  6009.       clip_info->height=0;
  6010.     }
  6011.   if ((clip_info->width != 0) && (clip_info->height != 0))
  6012.     target_window=root_window;
  6013.   return(target_window);
  6014. }
  6015.  
  6016. /*
  6017. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6018. %                                                                             %
  6019. %                                                                             %
  6020. %                                                                             %
  6021. %   X S e t W i n d o w E x t e n t s                                         %
  6022. %                                                                             %
  6023. %                                                                             %
  6024. %                                                                             %
  6025. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6026. %
  6027. %  Function XSetWindowExtents resizes the window to a size determined by the
  6028. %  text and the font size.
  6029. %
  6030. %  The format of the XSetWindowExtents function is:
  6031. %
  6032. %      XSetWindowExtents(display,window,text)
  6033. %
  6034. %  A description of each parameter follows:
  6035. %
  6036. %    o display: Specifies a pointer to the Display structure;  returned from
  6037. %      XOpenDisplay.
  6038. %
  6039. %    o window: Specifies a pointer to a XWindowInfo structure.
  6040. %
  6041. %    o text: Specifies a pointer to a text string.
  6042. %
  6043. %
  6044. */
  6045. void XSetWindowExtents(display,window,text)
  6046. Display
  6047.   *display;
  6048.  
  6049. XWindowInfo
  6050.   *window;
  6051.  
  6052. char
  6053.   *text;
  6054. {
  6055.   unsigned int
  6056.     height;
  6057.  
  6058.   XWindowChanges
  6059.     window_changes;
  6060.  
  6061.   window->width=XTextWidth(window->font_info,text,strlen(text))+
  6062.     ((3*window->font_info->max_bounds.width) >> 1);
  6063.   height=window->font_info->ascent+window->font_info->descent;
  6064.   window->height=(5*height) >> 2;
  6065.   window_changes.width=window->width;
  6066.   window_changes.height=window->height;
  6067.   XReconfigureWMWindow(display,window->id,window->screen,CWWidth | CWHeight,
  6068.     &window_changes);
  6069. }
  6070.  
  6071. /*
  6072. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6073. %                                                                             %
  6074. %                                                                             %
  6075. %                                                                             %
  6076. %   X V i s u a l C l a s s N a m e                                           %
  6077. %                                                                             %
  6078. %                                                                             %
  6079. %                                                                             %
  6080. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6081. %
  6082. %  Function XVisualClassName returns the visual class name as a character
  6083. %  string.
  6084. %
  6085. %  The format of the XVisualClassName routine is:
  6086. %
  6087. %      visual_type=XVisualClassName(class)
  6088. %
  6089. %  A description of each parameter follows:
  6090. %
  6091. %    o visual_type: XVisualClassName returns the visual class as a character
  6092. %      string.
  6093. %
  6094. %    o class: Specifies the visual class.
  6095. %
  6096. %
  6097. */
  6098. char *XVisualClassName(class)
  6099. int
  6100.   class;
  6101. {
  6102.   switch (class)
  6103.   {
  6104.     case StaticGray: return("StaticGray");
  6105.     case GrayScale: return("GrayScale");
  6106.     case StaticColor: return("StaticColor");
  6107.     case PseudoColor: return("PseudoColor");
  6108.     case TrueColor: return("TrueColor");
  6109.     case DirectColor: return("DirectColor");
  6110.   }
  6111.   return("unknown visual class");
  6112. }
  6113.  
  6114. /*
  6115. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6116. %                                                                             %
  6117. %                                                                             %
  6118. %                                                                             %
  6119. %   X W i n d o w B y I D                                                     %
  6120. %                                                                             %
  6121. %                                                                             %
  6122. %                                                                             %
  6123. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6124. %
  6125. %  Function XWindowByID locates a child window with a given ID.  If not window
  6126. %  with the given name is found, 0 is returned.   Only the window specified
  6127. %  and its subwindows are searched.
  6128. %
  6129. %  The format of the XWindowByID function is:
  6130. %
  6131. %      child=XWindowByID(display,window,id)
  6132. %
  6133. %  A description of each parameter follows:
  6134. %
  6135. %    o child: XWindowByID returns the window with the specified
  6136. %      id.  If no windows are found, XWindowByID returns 0.
  6137. %
  6138. %    o display: Specifies a pointer to the Display structure;  returned from
  6139. %      XOpenDisplay.
  6140. %
  6141. %    o id: Specifies the id of the window to locate.
  6142. %
  6143. %
  6144. */
  6145. Window XWindowByID(display,root_window,id)
  6146. Display
  6147.   *display;
  6148.  
  6149. Window
  6150.   root_window;
  6151.  
  6152. unsigned long
  6153.   id;
  6154. {
  6155.   register int
  6156.     i;
  6157.  
  6158.   unsigned int
  6159.     number_children;
  6160.  
  6161.   Window
  6162.     child,
  6163.     *children,
  6164.     window;
  6165.  
  6166.   if (root_window == id)
  6167.     return(id);
  6168.   if (!XQueryTree(display,root_window,&child,&child,&children,&number_children))
  6169.     return((Window) NULL);
  6170.   window=(Window) NULL;
  6171.   for (i=0; i < number_children; i++)
  6172.   {
  6173.     /*
  6174.       Search each child and their children.
  6175.     */
  6176.     window=XWindowByID(display,children[i],id);
  6177.     if (window != (Window) NULL)
  6178.       break;
  6179.   }
  6180.   if (children != (Window *) NULL)
  6181.     XFree((void *) children);
  6182.   return(window);
  6183. }
  6184.  
  6185. /*
  6186. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6187. %                                                                             %
  6188. %                                                                             %
  6189. %                                                                             %
  6190. %   X W i n d o w B y N a m e                                                 %
  6191. %                                                                             %
  6192. %                                                                             %
  6193. %                                                                             %
  6194. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6195. %
  6196. %  Function XWindowByName locates a window with a given name on a display.
  6197. %  If no window with the given name is found, 0 is returned. If more than
  6198. %  one window has the given name, the first one is returned.  Only root and
  6199. %  its children are searched.
  6200. %
  6201. %  The format of the XWindowByName function is:
  6202. %
  6203. %      window=XWindowByName(display,root_window,name)
  6204. %
  6205. %  A description of each parameter follows:
  6206. %
  6207. %    o window: XWindowByName returns the window id.
  6208. %
  6209. %    o display: Specifies a pointer to the Display structure;  returned from
  6210. %      XOpenDisplay.
  6211. %
  6212. %    o root_window: Specifies the id of the root window.
  6213. %
  6214. %    o name: Specifies the name of the window to locate.
  6215. %
  6216. %
  6217. */
  6218. Window XWindowByName(display,root_window,name)
  6219. Display
  6220.   *display;
  6221.  
  6222. Window
  6223.   root_window;
  6224.  
  6225. char
  6226.   *name;
  6227. {
  6228.   register int
  6229.     i;
  6230.  
  6231.   unsigned int
  6232.     number_children;
  6233.  
  6234.   Window
  6235.     *children,
  6236.     child,
  6237.     window;
  6238.  
  6239.   XTextProperty
  6240.     window_name;
  6241.  
  6242.   if (XGetWMName(display,root_window,&window_name) != 0)
  6243.     if (strcmp((char *) window_name.value,name) == 0)
  6244.       return(root_window);
  6245.   if (!XQueryTree(display,root_window,&child,&child,&children,&number_children))
  6246.     return((Window) NULL);
  6247.   window=(Window) NULL;
  6248.   for (i=0; i < number_children; i++)
  6249.   {
  6250.     /*
  6251.       Search each child and their children.
  6252.     */
  6253.     window=XWindowByName(display,children[i],name);
  6254.     if (window != (Window) NULL)
  6255.       break;
  6256.   }
  6257.   if (children != (Window *) NULL)
  6258.     XFree((void *) children);
  6259.   return(window);
  6260. }
  6261.  
  6262. /*
  6263. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6264. %                                                                             %
  6265. %                                                                             %
  6266. %                                                                             %
  6267. %   X W i n d o w B y P r o p e r y                                           %
  6268. %                                                                             %
  6269. %                                                                             %
  6270. %                                                                             %
  6271. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6272. %
  6273. %  Function XWindowByProperty locates a child window with a given property.
  6274. %  If no window with the given name is found, 0 is returned.  If more than
  6275. %  one window has the given property, the first one is returned.  Only the
  6276. %  window specified and its subwindows are searched.
  6277. %
  6278. %  The format of the XWindowByProperty function is:
  6279. %
  6280. %      child=XWindowByProperty(display,window,property)
  6281. %
  6282. %  A description of each parameter follows:
  6283. %
  6284. %    o child: XWindowByProperty returns the window id with the specified
  6285. %      property.  If no windows are found, XWindowByProperty returns 0.
  6286. %
  6287. %    o display: Specifies a pointer to the Display structure;  returned from
  6288. %      XOpenDisplay.
  6289. %
  6290. %    o property: Specifies the property of the window to locate.
  6291. %
  6292. %
  6293. */
  6294. static Window XWindowByProperty(display,window,property)
  6295. Display
  6296.   *display;
  6297.  
  6298. Window
  6299.   window;
  6300.  
  6301. Atom
  6302.   property;
  6303. {
  6304.   Atom
  6305.     type;
  6306.  
  6307.   int
  6308.     format,
  6309.     status;
  6310.  
  6311.   unsigned char
  6312.     *data;
  6313.  
  6314.   unsigned int
  6315.     i,
  6316.     number_children;
  6317.  
  6318.   unsigned long
  6319.     after,
  6320.     number_items;
  6321.  
  6322.   Window
  6323.     child,
  6324.     *children,
  6325.     parent,
  6326.     root;
  6327.  
  6328.   status=XQueryTree(display,window,&root,&parent,&children,&number_children);
  6329.   if (status == 0)
  6330.     return((Window) NULL);
  6331.   type=(Atom) NULL;
  6332.   child=(Window) NULL;
  6333.   for (i=0; (i < number_children) && (child == (Window) NULL); i++)
  6334.   {
  6335.     status=XGetWindowProperty(display,children[i],property,0L,0L,False,
  6336.       (Atom) AnyPropertyType,&type,&format,&number_items,&after,&data);
  6337.     if ((status == Success) && (type != (Atom) NULL))
  6338.       child=children[i];
  6339.   }
  6340.   for (i=0; (i < number_children) && (child == (Window) NULL); i++)
  6341.     child=XWindowByProperty(display,children[i],property);
  6342.   if (children != (Window *) NULL)
  6343.     XFree((void *) children);
  6344.   return(child);
  6345. }
  6346.